Merge pull request #10505 from hvitved/dataflow/viable-impl-in-ctx-consistency

Data flow: Guard against `viableImplInCallContext` not being a subset of `viableCallable`
This commit is contained in:
Tom Hvitved 2022-09-23 10:38:48 +02:00 коммит произвёл GitHub
Родитель cee0e8e137 914c711940
Коммит 8b424d181a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
43 изменённых файлов: 175 добавлений и 12 удалений

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}

Просмотреть файл

@ -87,3 +87,4 @@ postWithInFlow
| test.cpp:465:3:465:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:465:4:465:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:470:22:470:22 | x [inner post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge

Просмотреть файл

@ -627,3 +627,4 @@ postWithInFlow
| true_upon_entry.cpp:98:7:98:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:101:18:101:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:102:5:102:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge

Просмотреть файл

@ -155,3 +155,4 @@ postWithInFlow
| simple.cpp:92:7:92:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| struct_init.c:24:11:24:12 | ab [inner post update] | PostUpdateNode should not be the target of local flow. |
| struct_init.c:36:17:36:24 | nestedAB [inner post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge

Просмотреть файл

@ -1323,3 +1323,4 @@ postWithInFlow
| struct_init.c:46:16:46:24 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
| struct_init.c:46:16:46:24 | pointerAB [post update] | PostUpdateNode should not be the target of local flow. |
| struct_init.c:46:16:46:24 | pointerAB [post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge

Просмотреть файл

@ -124,3 +124,4 @@ postWithInFlow
| static_init_templates.cpp:3:2:3:4 | ref [post update] | PostUpdateNode should not be the target of local flow. |
| static_init_templates.cpp:21:2:21:4 | val [post update] | PostUpdateNode should not be the target of local flow. |
| try_catch.cpp:7:8:7:8 | call to exception | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge

Просмотреть файл

@ -2710,3 +2710,4 @@ postWithInFlow
| whilestmt.c:11:5:11:8 | done [post update] | PostUpdateNode should not be the target of local flow. |
| whilestmt.c:40:7:40:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| whilestmt.c:42:7:42:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge

Просмотреть файл

@ -175,10 +175,19 @@ private module DispatchImpl {
* restricted to those `call`s for which a context might make a difference.
*/
DataFlowCallable viableImplInCallContext(NonDelegateDataFlowCall call, DataFlowCall ctx) {
result.getUnderlyingCallable() =
call.getDispatchCall()
.getADynamicTargetInCallContext(ctx.(NonDelegateDataFlowCall).getDispatchCall())
.getUnboundDeclaration()
exists(DispatchCall dc | dc = call.getDispatchCall() |
result.getUnderlyingCallable() =
getCallableForDataFlow(dc.getADynamicTargetInCallContext(ctx.(NonDelegateDataFlowCall)
.getDispatchCall()).getUnboundDeclaration())
or
exists(Callable c, DataFlowCallable encl |
result.asSummarizedCallable() = c and
mayBenefitFromCallContext(call, encl) and
encl = ctx.getARuntimeTarget() and
c = dc.getAStaticTarget().getUnboundDeclaration() and
not c instanceof RuntimeCallable
)
)
}
}

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -16,3 +16,4 @@ postIsInSameCallable
reverseRead
argHasPostUpdate
postWithInFlow
viableImplInCallContextTooLarge

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}

Просмотреть файл

@ -709,7 +709,8 @@ private module Cached {
*/
pragma[nomagic]
private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx)
result = viableImplInCallContext(call, ctx) and
result = viableCallable(call)
or
result = viableCallableLambda(call, TDataFlowCallSome(ctx))
or

Просмотреть файл

@ -38,6 +38,13 @@ module Consistency {
/** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */
predicate uniquePostUpdateExclude(Node n) { none() }
/** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */
predicate viableImplInCallContextTooLargeExclude(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
none()
}
}
private class RelevantNode extends Node {
@ -217,4 +224,12 @@ module Consistency {
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
msg = "PostUpdateNode should not be the target of local flow."
}
query predicate viableImplInCallContextTooLarge(
DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable
) {
callable = viableImplInCallContext(call, ctx) and
not callable = viableCallable(call) and
not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable)
}
}