Skip to content

Commit c239197

Browse files
author
Nikita Kraiouchkine
committed
EXP43-C: swap PointsTo with data-flow and fix typo
1 parent a390e54 commit c239197

9 files changed

+57
-34
lines changed

c/cert/src/rules/EXP43-C/DoNotPassAlisedPointerToRestrictQualifiedParameter.ql renamed to c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* @id c/cert/do-not-pass-alised-pointer-to-restrict-qualified-parameter
2+
* @id c/cert/do-not-pass-aliased-pointer-to-restrict-qualified-param
33
* @name EXP43-C: Do not pass aliased pointers to restrict-qualified parameters
44
* @description Passing an aliased pointer to a restrict-qualified parameter is undefined behavior.
55
* @kind problem
@@ -13,7 +13,8 @@
1313
import cpp
1414
import codingstandards.c.cert
1515
import codingstandards.c.Pointers
16-
import semmle.code.cpp.dataflow.DataFlow
16+
import codingstandards.c.Variable
17+
import semmle.code.cpp.ir.dataflow.DataFlow
1718
import semmle.code.cpp.pointsto.PointsTo
1819
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1920

@@ -67,10 +68,9 @@ class CallToFunctionWithRestrictParameters extends FunctionCall {
6768
/**
6869
* A `PointsToExpr` that is an argument of a pointer-type in a `CallToFunctionWithRestrictParameters`
6970
*/
70-
class ArgPointsToExpr extends PointsToExpr {
71-
override predicate interesting() {
72-
any(CallToFunctionWithRestrictParameters call).getAnArgument() = this and
73-
pointerValue(this)
71+
class CallToFunctionWithRestrictParametersArgExpr extends Expr {
72+
CallToFunctionWithRestrictParametersArgExpr() {
73+
this = any(CallToFunctionWithRestrictParameters call).getAPtrArg()
7474
}
7575
}
7676

@@ -82,7 +82,7 @@ int getStatedValue(Expr e) {
8282
.minimum(min(Expr source | DataFlow::localExprFlow(source, e) | source.getValue().toInt()))
8383
}
8484

85-
int getPointerArithmeticOperandStatedValue(ArgPointsToExpr expr) {
85+
int getPointerArithmeticOperandStatedValue(CallToFunctionWithRestrictParametersArgExpr expr) {
8686
result = getStatedValue(expr.(PointerArithmeticExpr).getOperand())
8787
or
8888
// edge-case: &(array[index]) expressions
@@ -94,18 +94,37 @@ int getPointerArithmeticOperandStatedValue(ArgPointsToExpr expr) {
9494
result = 0
9595
}
9696

97+
class PointerValueToRestrictArgConfig extends DataFlow::Configuration {
98+
PointerValueToRestrictArgConfig() { this = "PointerValueToRestrictArgConfig" }
99+
100+
override predicate isSource(DataFlow::Node source) { pointerValue(source.asExpr()) }
101+
102+
override predicate isSink(DataFlow::Node sink) {
103+
exists(CallToFunctionWithRestrictParameters call |
104+
sink.asExpr() = call.getAPtrArg().getAChild*()
105+
)
106+
}
107+
}
108+
97109
from
98-
CallToFunctionWithRestrictParameters call, ArgPointsToExpr arg1, ArgPointsToExpr arg2,
99-
int argOffset1, int argOffset2
110+
CallToFunctionWithRestrictParameters call, CallToFunctionWithRestrictParametersArgExpr arg1,
111+
CallToFunctionWithRestrictParametersArgExpr arg2, int argOffset1, int argOffset2
100112
where
101-
not isExcluded(call, Pointers3Package::doNotPassAlisedPointerToRestrictQualifiedParameterQuery()) and
113+
not isExcluded(call, Pointers3Package::doNotPassAliasedPointerToRestrictQualifiedParamQuery()) and
102114
arg1 = call.getARestrictPtrArg() and
103115
arg2 = call.getAPtrArg() and
104-
// two arguments that point to the same object
105116
arg1 != arg2 and
106-
arg1.pointsTo() = arg2.pointsTo() and
107-
arg1.confidence() = 1.0 and
108-
arg2.confidence() = 1.0 and
117+
exists(PointerValueToRestrictArgConfig config, Expr source1, Expr source2 |
118+
config.hasFlow(DataFlow::exprNode(source1), DataFlow::exprNode(arg1.getAChild*())) and
119+
(
120+
// one pointer value flows to both args
121+
config.hasFlow(DataFlow::exprNode(source1), DataFlow::exprNode(arg2.getAChild*()))
122+
or
123+
// there are two separate values that flow from an AddressOfExpr of the same target
124+
getAddressOfExprTargetBase(source1) = getAddressOfExprTargetBase(source2) and
125+
config.hasFlow(DataFlow::exprNode(source2), DataFlow::exprNode(arg2.getAChild*()))
126+
)
127+
) and
109128
// get the offset of the pointer arithmetic operand (or '0' if there is none)
110129
argOffset1 = getPointerArithmeticOperandStatedValue(arg1) and
111130
argOffset2 = getPointerArithmeticOperandStatedValue(arg2) and

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import cpp
1414
import semmle.code.cpp.dataflow.DataFlow
1515
import semmle.code.cpp.controlflow.Dominance
1616
import codingstandards.c.cert
17+
import codingstandards.c.Variable
1718

1819
/**
1920
* An `Expr` that is an assignment or initialization to a restrict-qualified pointer-type variable.
@@ -29,16 +30,6 @@ class AssignmentOrInitializationToRestrictPtrValueExpr extends Expr {
2930
Variable getVariable() { result = v }
3031
}
3132

32-
/**
33-
* Returns the target variable of a `VariableAccess`.
34-
* If the access is a field access, then the target is the `Variable` of the qualifier.
35-
*/
36-
Variable getAddressOfExprTargetBase(AddressOfExpr expr) {
37-
result = expr.getOperand().(ValueFieldAccess).getQualifier().(VariableAccess).getTarget()
38-
or
39-
result = expr.getOperand().(VariableAccess).getTarget()
40-
}
41-
4233
/**
4334
* A data-flow configuration for tracking flow from an assignment or initialization to
4435
* an assignment to an `AssignmentOrInitializationToRestrictPtrValueExpr`.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql

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

Lines changed: 0 additions & 1 deletion
This file was deleted.

c/common/src/codingstandards/c/Variable.qll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,16 @@ class FlexibleArrayMemberCandidate extends MemberVariable {
3838
)
3939
}
4040
}
41+
42+
/**
43+
* Returns the target variable of a `VariableAccess`.
44+
* If the access is a field access, then the target is the `Variable` of the qualifier.
45+
* If the access is an array access, then the target is the array base.
46+
*/
47+
Variable getAddressOfExprTargetBase(AddressOfExpr expr) {
48+
result = expr.getOperand().(ValueFieldAccess).getQualifier().(VariableAccess).getTarget()
49+
or
50+
result = expr.getOperand().(VariableAccess).getTarget()
51+
or
52+
result = expr.getOperand().(ArrayExpr).getArrayBase().(VariableAccess).getTarget()
53+
}

cpp/common/src/codingstandards/cpp/exclusions/c/Pointers3.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ newtype Pointers3Query =
77
TDoNotAccessVolatileObjectWithNonVolatileReferenceQuery() or
88
TDoNotCastPointerToMoreStrictlyAlignedPointerTypeQuery() or
99
TDoNotAccessVariableViaPointerOfIncompatibleTypeQuery() or
10-
TDoNotPassAlisedPointerToRestrictQualifiedParameterQuery() or
10+
TDoNotPassAliasedPointerToRestrictQualifiedParamQuery() or
1111
TRestrictPointerReferencesOverlappingObjectQuery()
1212

1313
predicate isPointers3QueryMetadata(Query query, string queryId, string ruleId, string category) {
@@ -39,11 +39,11 @@ predicate isPointers3QueryMetadata(Query query, string queryId, string ruleId, s
3939
category = "rule"
4040
or
4141
query =
42-
// `Query` instance for the `doNotPassAlisedPointerToRestrictQualifiedParameter` query
43-
Pointers3Package::doNotPassAlisedPointerToRestrictQualifiedParameterQuery() and
42+
// `Query` instance for the `doNotPassAliasedPointerToRestrictQualifiedParam` query
43+
Pointers3Package::doNotPassAliasedPointerToRestrictQualifiedParamQuery() and
4444
queryId =
45-
// `@id` for the `doNotPassAlisedPointerToRestrictQualifiedParameter` query
46-
"c/cert/do-not-pass-alised-pointer-to-restrict-qualified-parameter" and
45+
// `@id` for the `doNotPassAliasedPointerToRestrictQualifiedParam` query
46+
"c/cert/do-not-pass-aliased-pointer-to-restrict-qualified-param" and
4747
ruleId = "EXP43-C" and
4848
category = "rule"
4949
or
@@ -79,11 +79,11 @@ module Pointers3Package {
7979
TQueryC(TPointers3PackageQuery(TDoNotAccessVariableViaPointerOfIncompatibleTypeQuery()))
8080
}
8181

82-
Query doNotPassAlisedPointerToRestrictQualifiedParameterQuery() {
82+
Query doNotPassAliasedPointerToRestrictQualifiedParamQuery() {
8383
//autogenerate `Query` type
8484
result =
85-
// `Query` type for `doNotPassAlisedPointerToRestrictQualifiedParameter` query
86-
TQueryC(TPointers3PackageQuery(TDoNotPassAlisedPointerToRestrictQualifiedParameterQuery()))
85+
// `Query` type for `doNotPassAliasedPointerToRestrictQualifiedParam` query
86+
TQueryC(TPointers3PackageQuery(TDoNotPassAliasedPointerToRestrictQualifiedParamQuery()))
8787
}
8888

8989
Query restrictPointerReferencesOverlappingObjectQuery() {

rule_packages/c/Pointers3.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"name": "Do not pass aliased pointers to restrict-qualified parameters",
7272
"precision": "medium",
7373
"severity": "error",
74-
"short_name": "DoNotPassAlisedPointerToRestrictQualifiedParameter",
74+
"short_name": "DoNotPassAliasedPointerToRestrictQualifiedParam",
7575
"tags": [
7676
"correctness"
7777
]

0 commit comments

Comments
 (0)