Skip to content

Commit a390e54

Browse files
author
Nikita Kraiouchkine
committed
Update EXP43-C query and test
Replace local with global data-flow. Modify the query implementation to detect violations of aliasing at block rather than statement scope as defined in the standard.
1 parent de6cd01 commit a390e54

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,26 @@ Variable getAddressOfExprTargetBase(AddressOfExpr expr) {
3939
result = expr.getOperand().(VariableAccess).getTarget()
4040
}
4141

42+
/**
43+
* A data-flow configuration for tracking flow from an assignment or initialization to
44+
* an assignment to an `AssignmentOrInitializationToRestrictPtrValueExpr`.
45+
*/
46+
class AssignedValueToRestrictPtrValueConfiguration extends DataFlow::Configuration {
47+
AssignedValueToRestrictPtrValueConfiguration() {
48+
this = "AssignmentOrInitializationToRestrictPtrValueConfiguration"
49+
}
50+
51+
override predicate isSource(DataFlow::Node source) {
52+
exists(Variable v | source.asExpr() = v.getAnAssignedValue())
53+
}
54+
55+
override predicate isSink(DataFlow::Node sink) {
56+
sink.asExpr() instanceof AssignmentOrInitializationToRestrictPtrValueExpr
57+
}
58+
}
59+
4260
from
43-
AssignmentOrInitializationToRestrictPtrValueExpr source,
61+
AssignedValueToRestrictPtrValueConfiguration config, DataFlow::Node sourceValue,
4462
AssignmentOrInitializationToRestrictPtrValueExpr expr,
4563
AssignmentOrInitializationToRestrictPtrValueExpr pre_expr
4664
where
@@ -49,23 +67,14 @@ where
4967
// If the same expressions flows to two unique `AssignmentOrInitializationToRestrictPtrValueExpr`
5068
// in the same block, then the two variables point to the same (overlapping) object
5169
expr.getEnclosingBlock() = pre_expr.getEnclosingBlock() and
52-
strictlyDominates(pre_expr, expr) and
5370
(
54-
dominates(source, pre_expr) and
55-
DataFlow::localExprFlow(source, expr) and
56-
DataFlow::localExprFlow(source, pre_expr)
71+
config.hasFlow(sourceValue, DataFlow::exprNode(pre_expr)) and
72+
config.hasFlow(sourceValue, DataFlow::exprNode(expr))
5773
or
5874
// Expressions referring to the address of the same variable can also result in aliasing
59-
getAddressOfExprTargetBase(expr) = getAddressOfExprTargetBase(pre_expr) and
60-
source =
61-
any(AddressOfExpr ao | getAddressOfExprTargetBase(ao) = getAddressOfExprTargetBase(expr))
75+
getAddressOfExprTargetBase(expr) = getAddressOfExprTargetBase(pre_expr)
6276
) and
63-
// But only if there is no intermediate assignment that could change the value of one of the variables
64-
not exists(AssignmentOrInitializationToRestrictPtrValueExpr mid |
65-
strictlyDominates(mid, expr) and
66-
strictlyDominates(pre_expr, mid) and
67-
not DataFlow::localExprFlow(source, mid)
68-
)
77+
strictlyDominates(pragma[only_bind_out](pre_expr), pragma[only_bind_out](expr))
6978
or
7079
// Two restrict-qualified pointers in the same scope assigned to each other
7180
expr.(VariableAccess).getTarget().getType().hasSpecifier("restrict") and
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
| test.c:18:22:18:23 | i2 | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:18:17:18:18 | i3 | i3 |
22
| test.c:19:8:19:9 | g2 | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:5:15:5:16 | g1 | g1 |
33
| test.c:20:8:20:9 | i2 | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:16:17:16:18 | i1 | i1 |
4+
| test.c:27:10:27:11 | g1 | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:23:19:23:20 | i5 | i5 |
45
| test.c:28:10:28:11 | g1 | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:22:19:22:20 | i4 | i4 |
56
| test.c:39:22:39:26 | & ... | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:39:17:39:18 | px | px |
7+
| test.c:45:10:45:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:42:19:42:20 | pz | pz |
68
| test.c:46:10:46:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointer aliasing. | test.c:41:19:41:20 | py | py |

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ void test_global_local() {
2424
int *restrict i6;
2525
i4 = g1; // COMPLIANT
2626
i4 = (void *)0; // COMPLIANT
27-
i5 = g1; // COMPLIANT
27+
i5 = g1; // NON_COMPLIANT - block rather than statement scope matters
2828
i4 = g1; // NON_COMPLIANT
2929
i6 = g2; // COMPLIANT
3030
}
@@ -42,7 +42,7 @@ void test_structs() {
4242
int *restrict pz;
4343
py = &v1.y; // COMPLIANT
4444
py = (int *)0;
45-
pz = &v1.z; // COMPLIANT
45+
pz = &v1.z; // NON_COMPLIANT - block rather than statement scope matters
4646
py = &v1.y; // NON_COMPLIANT
4747
}
4848
}

0 commit comments

Comments
 (0)