Ruby: Summarize load-store steps in type-tracking

fixup to LoadStore
This commit is contained in:
Asger F
2022-09-30 10:08:34 +02:00
parent a4d4e406c6
commit 0000a7d429
2 changed files with 59 additions and 0 deletions

View File

@@ -14,6 +14,9 @@ private module Cached {
ReturnStep() or
StoreStep(TypeTrackerContent content) { basicStoreStep(_, _, content) } or
LoadStep(TypeTrackerContent content) { basicLoadStep(_, _, content) } or
LoadStoreStep(TypeTrackerContent load, TypeTrackerContent store) {
basicLoadStoreStep(_, _, load, store)
} or
JumpStep()
cached
@@ -75,6 +78,16 @@ private module Cached {
tt = noContentTypeTracker(hasCall) and
result = MkTypeTracker(hasCall, storeContents)
)
or
exists(
TypeTrackerContent currentContent, TypeTrackerContent store, TypeTrackerContent load,
boolean hasCall
|
step = LoadStoreStep(pragma[only_bind_into](load), pragma[only_bind_into](store)) and
compatibleContents(pragma[only_bind_into](currentContent), load) and
tt = MkTypeTracker(pragma[only_bind_into](hasCall), currentContent) and
result = MkTypeTracker(pragma[only_bind_out](hasCall), store)
)
}
pragma[nomagic]
@@ -110,6 +123,16 @@ private module Cached {
tbt = noContentTypeBackTracker(hasReturn) and
result = MkTypeBackTracker(hasReturn, loadContents)
)
or
exists(
TypeTrackerContent currentContent, TypeTrackerContent store, TypeTrackerContent load,
boolean hasCall
|
step = LoadStoreStep(pragma[only_bind_into](load), pragma[only_bind_into](store)) and
compatibleContents(store, pragma[only_bind_into](currentContent)) and
tbt = MkTypeBackTracker(pragma[only_bind_into](hasCall), currentContent) and
result = MkTypeBackTracker(pragma[only_bind_out](hasCall), load)
)
}
/**
@@ -146,6 +169,11 @@ private module Cached {
or
basicLoadStep(nodeFrom, nodeTo, content) and summary = LoadStep(content)
)
or
exists(TypeTrackerContent loadContent, TypeTrackerContent storeContent |
basicLoadStoreStep(nodeFrom, nodeTo, loadContent, storeContent) and
summary = LoadStoreStep(loadContent, storeContent)
)
}
cached
@@ -208,6 +236,11 @@ class StepSummary extends TStepSummary {
or
exists(TypeTrackerContent content | this = LoadStep(content) | result = "load " + content)
or
exists(TypeTrackerContent load, TypeTrackerContent store |
this = LoadStoreStep(load, store) and
result = "load-store " + load + " -> " + store
)
or
this instanceof JumpStep and result = "jump"
}
}

View File

@@ -231,6 +231,23 @@ predicate basicLoadStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet content
)
}
/**
* Holds if the `loadContent` of `nodeFrom` is stored in the `storeContent` of `nodeTo`.
*/
predicate basicLoadStoreStep(
Node nodeFrom, Node nodeTo, DataFlow::ContentSet loadContent, DataFlow::ContentSet storeContent
) {
exists(
SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponent input,
SummaryComponent output
|
hasLoadStoreSummary(callable, loadContent, storeContent, input, output) and
call.asExpr().getExpr() = callable.getACallSimple() and
nodeFrom = evaluateSummaryComponentLocal(call, input) and
nodeTo = evaluateSummaryComponentLocal(call, output)
)
}
/**
* A utility class that is equivalent to `boolean` but does not require type joining.
*/
@@ -264,6 +281,15 @@ private predicate hasLoadSummary(
singleton(output), true)
}
private predicate hasLoadStoreSummary(
SummarizedCallable callable, DataFlow::ContentSet loadContents,
DataFlow::ContentSet storeContents, SummaryComponent input, SummaryComponent output
) {
callable
.propagatesFlow(push(SummaryComponent::content(loadContents), singleton(input)),
push(SummaryComponent::content(storeContents), singleton(output)), true)
}
/**
* Gets a data flow node corresponding an argument or return value of `call`,
* as specified by `component`.