From 73fd66cfed7083e334983df6fecdc18e50c87f34 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 12 Oct 2021 16:19:43 +0200 Subject: [PATCH 1/4] Python: Cache `TypeBackTracker::prepend` --- .../dataflow/new/internal/TypeTracker.qll | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll index 6ced6a8206e..50452012213 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll @@ -52,6 +52,24 @@ private module Cached { ) } + /** Gets the summary resulting from prepending `step` to this type-tracking summary. */ + cached + TypeBackTracker prepend(TypeBackTracker tbt, StepSummary step) { + exists(Boolean hasReturn, string content | tbt = MkTypeBackTracker(hasReturn, content) | + step = LevelStep() and result = tbt + or + step = CallStep() and hasReturn = false and result = tbt + or + step = ReturnStep() and result = MkTypeBackTracker(true, content) + or + exists(string p | + step = LoadStep(p) and content = "" and result = MkTypeBackTracker(hasReturn, p) + ) + or + step = StoreStep(content) and result = MkTypeBackTracker(hasReturn, "") + ) + } + /** * Gets the summary that corresponds to having taken a forwards * heap and/or intra-procedural step from `nodeFrom` to `nodeTo`. @@ -365,19 +383,7 @@ class TypeBackTracker extends TTypeBackTracker { TypeBackTracker() { this = MkTypeBackTracker(hasReturn, content) } /** Gets the summary resulting from prepending `step` to this type-tracking summary. */ - TypeBackTracker prepend(StepSummary step) { - step = LevelStep() and result = this - or - step = CallStep() and hasReturn = false and result = this - or - step = ReturnStep() and result = MkTypeBackTracker(true, content) - or - exists(string p | - step = LoadStep(p) and content = "" and result = MkTypeBackTracker(hasReturn, p) - ) - or - step = StoreStep(content) and result = MkTypeBackTracker(hasReturn, "") - } + TypeBackTracker prepend(StepSummary step) { result = prepend(this, step) } /** Gets a textual representation of this summary. */ string toString() { From 660398aa78958ccb38538c4c76c630eda62160dc Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 12 Oct 2021 16:20:07 +0200 Subject: [PATCH 2/4] Python: Introduce `TypeBackTracker::getACompatibleTypeTracker()` --- .../python/dataflow/new/internal/TypeTracker.qll | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll index 50452012213..d491904ce5d 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll @@ -465,6 +465,19 @@ class TypeBackTracker extends TTypeBackTracker { simpleLocalFlowStep(nodeFrom, nodeTo) and this = result } + + /** + * Gets a forwards summary that is compatible with this backwards summary. + * That is, if this summary describes the steps needed to back-track a value + * from `sink` to `mid`, and the result is a valid summary of the steps needed + * to track a value from `source` to `mid`, then the value from `source` may + * also flow to `sink`. + */ + TypeTracker getACompatibleTypeTracker() { + exists(boolean hasCall | result = MkTypeTracker(hasCall, content) | + hasCall = false or hasReturn() = false + ) + } } /** Provides predicates for implementing custom `TypeBackTracker`s. */ From 1e64893742ea679338a04611643e139d814cede1 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 31 Oct 2021 08:57:44 +0100 Subject: [PATCH 3/4] Update python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll Co-authored-by: Taus --- .../ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll index d491904ce5d..272e87b4995 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll @@ -475,7 +475,7 @@ class TypeBackTracker extends TTypeBackTracker { */ TypeTracker getACompatibleTypeTracker() { exists(boolean hasCall | result = MkTypeTracker(hasCall, content) | - hasCall = false or hasReturn() = false + hasCall = false or this.hasReturn() = false ) } } From fe80c4a17b42f48cf11ee5c5752cdb7d43882ff2 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 2 Nov 2021 11:16:46 +0100 Subject: [PATCH 4/4] Ruby: Sync files --- .../codeql/ruby/typetracking/TypeTracker.qll | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll index 6ced6a8206e..272e87b4995 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll @@ -52,6 +52,24 @@ private module Cached { ) } + /** Gets the summary resulting from prepending `step` to this type-tracking summary. */ + cached + TypeBackTracker prepend(TypeBackTracker tbt, StepSummary step) { + exists(Boolean hasReturn, string content | tbt = MkTypeBackTracker(hasReturn, content) | + step = LevelStep() and result = tbt + or + step = CallStep() and hasReturn = false and result = tbt + or + step = ReturnStep() and result = MkTypeBackTracker(true, content) + or + exists(string p | + step = LoadStep(p) and content = "" and result = MkTypeBackTracker(hasReturn, p) + ) + or + step = StoreStep(content) and result = MkTypeBackTracker(hasReturn, "") + ) + } + /** * Gets the summary that corresponds to having taken a forwards * heap and/or intra-procedural step from `nodeFrom` to `nodeTo`. @@ -365,19 +383,7 @@ class TypeBackTracker extends TTypeBackTracker { TypeBackTracker() { this = MkTypeBackTracker(hasReturn, content) } /** Gets the summary resulting from prepending `step` to this type-tracking summary. */ - TypeBackTracker prepend(StepSummary step) { - step = LevelStep() and result = this - or - step = CallStep() and hasReturn = false and result = this - or - step = ReturnStep() and result = MkTypeBackTracker(true, content) - or - exists(string p | - step = LoadStep(p) and content = "" and result = MkTypeBackTracker(hasReturn, p) - ) - or - step = StoreStep(content) and result = MkTypeBackTracker(hasReturn, "") - } + TypeBackTracker prepend(StepSummary step) { result = prepend(this, step) } /** Gets a textual representation of this summary. */ string toString() { @@ -459,6 +465,19 @@ class TypeBackTracker extends TTypeBackTracker { simpleLocalFlowStep(nodeFrom, nodeTo) and this = result } + + /** + * Gets a forwards summary that is compatible with this backwards summary. + * That is, if this summary describes the steps needed to back-track a value + * from `sink` to `mid`, and the result is a valid summary of the steps needed + * to track a value from `source` to `mid`, then the value from `source` may + * also flow to `sink`. + */ + TypeTracker getACompatibleTypeTracker() { + exists(boolean hasCall | result = MkTypeTracker(hasCall, content) | + hasCall = false or this.hasReturn() = false + ) + } } /** Provides predicates for implementing custom `TypeBackTracker`s. */