From b23ab8089ae5a314ac29fd42ad5d615e6106a30d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 3 Mar 2022 12:29:47 +0100 Subject: [PATCH 1/3] Ruby: Clear call contexts after jump steps in type tracking --- .../lib/codeql/ruby/typetracking/TypeTracker.qll | 14 +++++++++++++- .../ruby/typetracking/TypeTrackerSpecific.qll | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll index a77a0659f3be..c463d2139207 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll @@ -34,7 +34,8 @@ private module Cached { CallStep() or ReturnStep() or StoreStep(ContentName content) or - LoadStep(ContentName content) + LoadStep(ContentName content) or + JumpStep() /** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */ cached @@ -49,6 +50,9 @@ private module Cached { step = LoadStep(content) and result = MkTypeTracker(hasCall, "") or exists(string p | step = StoreStep(p) and content = "" and result = MkTypeTracker(hasCall, p)) + or + step = JumpStep() and + result = MkTypeTracker(false, content) ) } @@ -67,6 +71,9 @@ private module Cached { ) or step = StoreStep(content) and result = MkTypeBackTracker(hasReturn, "") + or + step = JumpStep() and + result = MkTypeBackTracker(false, content) ) } @@ -110,12 +117,17 @@ class StepSummary extends TStepSummary { exists(string content | this = StoreStep(content) | result = "store " + content) or exists(string content | this = LoadStep(content) | result = "load " + content) + or + this instanceof JumpStep and result = "jump" } } pragma[noinline] private predicate smallstepNoCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { jumpStep(nodeFrom, nodeTo) and + summary = JumpStep() + or + levelStep(nodeFrom, nodeTo) and summary = LevelStep() or exists(string content | diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index 4b37115b4e27..e5e149d02bc8 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -15,6 +15,8 @@ predicate simpleLocalFlowStep = DataFlowPrivate::localFlowStepTypeTracker/2; predicate jumpStep = DataFlowPrivate::jumpStep/2; +predicate levelStep(Node pred, Node succ) { none() } + /** * Gets the name of a possible piece of content. This will usually include things like * From ba6ff88d05bdd8d369c0007bb2fd6861f1752b87 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 3 Mar 2022 12:30:50 +0100 Subject: [PATCH 2/3] Sync files --- .../python/dataflow/new/internal/TypeTracker.qll | 14 +++++++++++++- .../dataflow/new/internal/TypeTrackerSpecific.qll | 2 ++ 2 files changed, 15 insertions(+), 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 a77a0659f3be..c463d2139207 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll @@ -34,7 +34,8 @@ private module Cached { CallStep() or ReturnStep() or StoreStep(ContentName content) or - LoadStep(ContentName content) + LoadStep(ContentName content) or + JumpStep() /** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */ cached @@ -49,6 +50,9 @@ private module Cached { step = LoadStep(content) and result = MkTypeTracker(hasCall, "") or exists(string p | step = StoreStep(p) and content = "" and result = MkTypeTracker(hasCall, p)) + or + step = JumpStep() and + result = MkTypeTracker(false, content) ) } @@ -67,6 +71,9 @@ private module Cached { ) or step = StoreStep(content) and result = MkTypeBackTracker(hasReturn, "") + or + step = JumpStep() and + result = MkTypeBackTracker(false, content) ) } @@ -110,12 +117,17 @@ class StepSummary extends TStepSummary { exists(string content | this = StoreStep(content) | result = "store " + content) or exists(string content | this = LoadStep(content) | result = "load " + content) + or + this instanceof JumpStep and result = "jump" } } pragma[noinline] private predicate smallstepNoCall(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) { jumpStep(nodeFrom, nodeTo) and + summary = JumpStep() + or + levelStep(nodeFrom, nodeTo) and summary = LevelStep() or exists(string content | diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index ac7d4ca5e3cd..38e06a68a419 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -14,6 +14,8 @@ predicate simpleLocalFlowStep = DataFlowPrivate::simpleLocalFlowStep/2; predicate jumpStep = DataFlowPrivate::jumpStep/2; +predicate levelStep(Node pred, Node succ) { none() } + /** * Gets the name of a possible piece of content. For Python, this is currently only attribute names, * using the name of the attribute for the corresponding content. From 9d6d479fbab820cce51d266ddc6f03e1a33289b7 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 3 Mar 2022 14:17:41 +0100 Subject: [PATCH 3/3] Add missing QL doc --- .../semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll | 1 + ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll | 1 + 2 files changed, 2 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll index 38e06a68a419..324e53a54ffb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackerSpecific.qll @@ -14,6 +14,7 @@ predicate simpleLocalFlowStep = DataFlowPrivate::simpleLocalFlowStep/2; predicate jumpStep = DataFlowPrivate::jumpStep/2; +/** Holds if there is a level step from `pred` to `succ`. */ predicate levelStep(Node pred, Node succ) { none() } /** diff --git a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll index e5e149d02bc8..e1c83273d822 100644 --- a/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll @@ -15,6 +15,7 @@ predicate simpleLocalFlowStep = DataFlowPrivate::localFlowStepTypeTracker/2; predicate jumpStep = DataFlowPrivate::jumpStep/2; +/** Holds if there is a level step from `pred` to `succ`. */ predicate levelStep(Node pred, Node succ) { none() } /**