Skip to content

Commit b3523be

Browse files
author
Nikita Kraiouchkine
committed
ARR38-C: Add missing GVN logic
1 parent 8ef1af9 commit b3523be

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

c/cert/test/rules/ARR38-C/test.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,10 @@ void test_read_file(const char *file_name) {
458458
fclose(f);
459459
}
460460

461-
void test_equivalent_expressions(void *in, int x, int y) {
461+
void test_equivalent_expressions(void *in, int x, int y, int a, int b) {
462462
short *p = malloc(x * y * sizeof(short));
463463
memcpy(p, in, x * y * sizeof(short)); // COMPLIANT
464464
memcpy(p, in, x * y * sizeof(short) + 1); // NON_COMPLIANT
465465
memcpy(p, in, x * y * sizeof(short) - 1); // COMPLIANT
466+
memcpy(p, in, a * b * sizeof(short) + 1); // COMPLIANT - unknown
466467
}

c/common/src/codingstandards/c/OutOfBounds.qll

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,37 @@ module OOB {
11291129
)
11301130
}
11311131

1132+
/**
1133+
* Holds if `a` and `b` are function calls to the same target function and
1134+
* have identical arguments (determined by their global value number or `VariableAccess` targets).
1135+
*/
1136+
bindingset[a, b]
1137+
private predicate areFunctionCallsSyntacticallySame(FunctionCall a, FunctionCall b) {
1138+
a.getTarget() = b.getTarget() and
1139+
(
1140+
exists(a.getAnArgument())
1141+
implies
1142+
not exists(int i, Expr argA, Expr argB |
1143+
i = [0 .. a.getTarget().getNumberOfParameters() - 1]
1144+
|
1145+
argA = a.getArgument(i) and
1146+
argB = b.getArgument(i) and
1147+
not globalValueNumber(argA) = globalValueNumber(argB) and
1148+
not argA.(VariableAccess).getTarget() = argB.(VariableAccess).getTarget()
1149+
)
1150+
)
1151+
}
1152+
1153+
/**
1154+
* Holds if `a` and `b` have the same global value number or are syntactically identical function calls
1155+
*/
1156+
bindingset[a, b]
1157+
private predicate isGVNOrFunctionCallSame(Expr a, Expr b) {
1158+
globalValueNumber(a) = globalValueNumber(b)
1159+
or
1160+
areFunctionCallsSyntacticallySame(a, b)
1161+
}
1162+
11321163
/**
11331164
* Holds if the BufferAccess is accessed with a `base + accessOffset` on a buffer that was
11341165
* allocated a size of the form `base + allocationOffset`.
@@ -1150,9 +1181,12 @@ module OOB {
11501181
sourceSizeExpr = source.getSizeExprSource(sourceSizeExprBase, sourceSizeExprOffset) and
11511182
bufferUseNonComputableSize(bufferArg, source) and
11521183
not globalValueNumber(sourceSizeExpr) = globalValueNumber(bufferSizeArg) and
1153-
sizeArgOffset = getArithmeticOffsetValue(bufferSizeArg.getAChild*(), _) and
1154-
bufferArgOffset = getArithmeticOffsetValue(bufferArg, _) and
1155-
sourceSizeExprOffset + bufferArgOffset < sizeArgOffset
1184+
exists(Expr sizeArgBase |
1185+
sizeArgOffset = getArithmeticOffsetValue(bufferSizeArg.getAChild*(), sizeArgBase) and
1186+
isGVNOrFunctionCallSame(sizeArgBase, sourceSizeExprBase) and
1187+
bufferArgOffset = getArithmeticOffsetValue(bufferArg, _) and
1188+
sourceSizeExprOffset + bufferArgOffset < sizeArgOffset
1189+
)
11561190
)
11571191
}
11581192

0 commit comments

Comments
 (0)