Skip to content

Commit 2644ca4

Browse files
committed
M0-2-1: make into split and shared query
moved some libraries to allow for use in shared query
1 parent 3fb6ac2 commit 2644ca4

File tree

31 files changed

+306
-200
lines changed

31 files changed

+306
-200
lines changed

c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import cpp
1515
import codingstandards.c.cert
16-
import codingstandards.c.Pointers
16+
import codingstandards.cpp.Pointers
1717
import codingstandards.cpp.dataflow.TaintTracking
1818
import ScaledIntegerPointerArithmeticFlow::PathGraph
1919

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

Lines changed: 6 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -12,177 +12,11 @@
1212

1313
import cpp
1414
import codingstandards.c.cert
15-
import codingstandards.c.Pointers
16-
import codingstandards.c.Variable
17-
import codingstandards.cpp.dataflow.DataFlow
18-
import semmle.code.cpp.pointsto.PointsTo
19-
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
15+
import codingstandards.cpp.rules.donotpassaliasedpointertorestrictqualifiedparam_shared.DoNotPassAliasedPointerToRestrictQualifiedParam_Shared
2016

21-
/**
22-
* A function that has a parameter with a restrict-qualified pointer type.
23-
*/
24-
class FunctionWithRestrictParameters extends Function {
25-
Parameter restrictPtrParam;
26-
27-
FunctionWithRestrictParameters() {
28-
restrictPtrParam.getUnspecifiedType() instanceof PointerOrArrayType and
29-
(
30-
restrictPtrParam.getType().hasSpecifier(["restrict"]) and
31-
restrictPtrParam = this.getAParameter()
32-
or
33-
this.hasGlobalName(["strcpy", "strncpy", "strcat", "strncat", "memcpy"]) and
34-
restrictPtrParam = this.getParameter([0, 1])
35-
or
36-
this.hasGlobalName(["strcpy_s", "strncpy_s", "strcat_s", "strncat_s", "memcpy_s"]) and
37-
restrictPtrParam = this.getParameter([0, 2])
38-
or
39-
this.hasGlobalName(["strtok_s"]) and
40-
restrictPtrParam = this.getAParameter()
41-
or
42-
this.hasGlobalName(["printf", "printf_s", "scanf", "scanf_s"]) and
43-
restrictPtrParam = this.getParameter(0)
44-
or
45-
this.hasGlobalName(["sprintf", "sprintf_s", "snprintf", "snprintf_s"]) and
46-
restrictPtrParam = this.getParameter(3)
47-
)
48-
}
49-
50-
Parameter getARestrictPtrParam() { result = restrictPtrParam }
51-
}
52-
53-
/**
54-
* A call to a function that has a parameter with a restrict-qualified pointer type.
55-
*/
56-
class CallToFunctionWithRestrictParameters extends FunctionCall {
57-
CallToFunctionWithRestrictParameters() {
58-
this.getTarget() instanceof FunctionWithRestrictParameters
17+
class DoNotPassAliasedPointerToRestrictQualifiedParamQuery extends DoNotPassAliasedPointerToRestrictQualifiedParam_SharedSharedQuery
18+
{
19+
DoNotPassAliasedPointerToRestrictQualifiedParamQuery() {
20+
this = Pointers3Package::doNotPassAliasedPointerToRestrictQualifiedParamQuery()
5921
}
60-
61-
Expr getARestrictPtrArg() {
62-
result =
63-
this.getArgument(this.getTarget()
64-
.(FunctionWithRestrictParameters)
65-
.getARestrictPtrParam()
66-
.getIndex())
67-
}
68-
69-
Expr getAPtrArg(int index) {
70-
result = this.getArgument(index) and
71-
pointerValue(result)
72-
}
73-
74-
Expr getAPossibleSizeArg() {
75-
exists(Parameter param |
76-
param = this.getTarget().(FunctionWithRestrictParameters).getAParameter() and
77-
param.getUnderlyingType() instanceof IntegralType and
78-
// exclude __builtin_object_size
79-
not result.(FunctionCall).getTarget() instanceof BuiltInFunction and
80-
result = this.getArgument(param.getIndex())
81-
)
82-
}
83-
}
84-
85-
/**
86-
* A `PointsToExpr` that is an argument of a pointer-type in a `CallToFunctionWithRestrictParameters`
87-
*/
88-
class CallToFunctionWithRestrictParametersArgExpr extends Expr {
89-
int paramIndex;
90-
91-
CallToFunctionWithRestrictParametersArgExpr() {
92-
this = any(CallToFunctionWithRestrictParameters call).getAPtrArg(paramIndex)
93-
}
94-
95-
int getParamIndex() { result = paramIndex }
96-
}
97-
98-
int getStatedValue(Expr e) {
99-
// `upperBound(e)` defaults to `exprMaxVal(e)` when `e` isn't analyzable. So to get a meaningful
100-
// result in this case we pick the minimum value obtainable from dataflow and range analysis.
101-
result =
102-
upperBound(e)
103-
.minimum(min(Expr source | DataFlow::localExprFlow(source, e) | source.getValue().toInt()))
104-
}
105-
106-
int getPointerArithmeticOperandStatedValue(CallToFunctionWithRestrictParametersArgExpr expr) {
107-
result = getStatedValue(expr.(PointerArithmeticExpr).getOperand())
108-
or
109-
// edge-case: &(array[index]) expressions
110-
result = getStatedValue(expr.(AddressOfExpr).getOperand().(PointerArithmeticExpr).getOperand())
111-
or
112-
// fall-back if `expr` is not a pointer arithmetic expression
113-
not expr instanceof PointerArithmeticExpr and
114-
not expr.(AddressOfExpr).getOperand() instanceof PointerArithmeticExpr and
115-
result = 0
116-
}
117-
118-
module PointerValueToRestrictArgConfig implements DataFlow::ConfigSig {
119-
predicate isSource(DataFlow::Node source) { pointerValue(source.asExpr()) }
120-
121-
predicate isSink(DataFlow::Node sink) {
122-
exists(CallToFunctionWithRestrictParameters call |
123-
sink.asExpr() = call.getAPtrArg(_).getAChild*()
124-
)
125-
}
126-
127-
predicate isBarrierIn(DataFlow::Node node) {
128-
exists(AddressOfExpr a | node.asExpr() = a.getOperand().getAChild*())
129-
}
130-
}
131-
132-
module PointerValueToRestrictArgFlow = DataFlow::Global<PointerValueToRestrictArgConfig>;
133-
134-
from
135-
CallToFunctionWithRestrictParameters call, CallToFunctionWithRestrictParametersArgExpr arg1,
136-
CallToFunctionWithRestrictParametersArgExpr arg2, int argOffset1, int argOffset2, Expr source1,
137-
Expr source2, string sourceMessage1, string sourceMessage2
138-
where
139-
not isExcluded(call, Pointers3Package::doNotPassAliasedPointerToRestrictQualifiedParamQuery()) and
140-
arg1 = call.getARestrictPtrArg() and
141-
arg2 = call.getAPtrArg(_) and
142-
// enforce ordering to remove permutations if multiple restrict-qualified args exist
143-
(not arg2 = call.getARestrictPtrArg() or arg2.getParamIndex() > arg1.getParamIndex()) and
144-
(
145-
// check if two pointers address the same object
146-
PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source1),
147-
DataFlow::exprNode(arg1.getAChild*())) and
148-
(
149-
// one pointer value flows to both args
150-
PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source1),
151-
DataFlow::exprNode(arg2.getAChild*())) and
152-
sourceMessage1 = "$@" and
153-
sourceMessage2 = "source" and
154-
source1 = source2
155-
or
156-
// there are two separate values that flow from an AddressOfExpr of the same target
157-
getAddressOfExprTargetBase(source1) = getAddressOfExprTargetBase(source2) and
158-
PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source2),
159-
DataFlow::exprNode(arg2.getAChild*())) and
160-
sourceMessage1 = "a pair of address-of expressions ($@, $@)" and
161-
sourceMessage2 = "addressof1" and
162-
not source1 = source2
163-
)
164-
) and
165-
// get the offset of the pointer arithmetic operand (or '0' if there is none)
166-
argOffset1 = getPointerArithmeticOperandStatedValue(arg1) and
167-
argOffset2 = getPointerArithmeticOperandStatedValue(arg2) and
168-
(
169-
// case 1: the pointer args are the same.
170-
// (definite aliasing)
171-
argOffset1 = argOffset2
172-
or
173-
// case 2: the pointer args are different, a size arg exists,
174-
// and the size arg is greater than the difference between the offsets.
175-
// (potential aliasing)
176-
exists(Expr sizeArg |
177-
sizeArg = call.getAPossibleSizeArg() and
178-
getStatedValue(sizeArg) > (argOffset1 - argOffset2).abs()
179-
)
180-
or
181-
// case 3: the pointer args are different, and a size arg does not exist
182-
// (potential aliasing)
183-
not exists(call.getAPossibleSizeArg())
184-
)
185-
select call,
186-
"Call to '" + call.getTarget().getName() + "' passes an $@ to a $@ (pointer value derived from " +
187-
sourceMessage1 + ".", arg2, "aliased pointer", arg1, "restrict-qualified parameter", source1,
188-
sourceMessage2, source2, "addressof2"
22+
}

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

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparam_shared/DoNotPassAliasedPointerToRestrictQualifiedParam_Shared.ql

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import cpp
8-
import codingstandards.c.Pointers
8+
import codingstandards.cpp.Pointers
99
import codingstandards.c.Variable
1010
import codingstandards.cpp.Allocations
1111
import codingstandards.cpp.Overflow

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,6 @@ class FlexibleArrayMemberCandidate extends MemberVariable {
3939
}
4040
}
4141

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-
not expr.getOperand() instanceof ValueFieldAccess and
51-
result = expr.getOperand().(VariableAccess).getTarget()
52-
or
53-
result = expr.getOperand().(ArrayExpr).getArrayBase().(VariableAccess).getTarget()
54-
}
55-
5642
/**
5743
* A struct that contains a flexible array member
5844
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.donotpassaliasedpointertorestrictqualifiedparam_shared.DoNotPassAliasedPointerToRestrictQualifiedParam_Shared
3+
4+
class TestFileQuery extends DoNotPassAliasedPointerToRestrictQualifiedParam_SharedSharedQuery,
5+
TestQuery
6+
{ }

c/misra/src/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import cpp
1515
import codingstandards.c.misra
16-
import codingstandards.c.Pointers
16+
import codingstandards.cpp.Pointers
1717

1818
from CStyleCast cast, Type type, Type newType
1919
where

c/misra/src/rules/RULE-11-2/ConversionBetweenIncompleteTypePointerAndOtherType.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import cpp
1515
import codingstandards.c.misra
16-
import codingstandards.c.Pointers
16+
import codingstandards.cpp.Pointers
1717
import codingstandards.cpp.Type
1818

1919
from Cast cast, Type type, Type newType

c/misra/src/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import cpp
1616
import codingstandards.c.misra
17-
import codingstandards.c.Pointers
17+
import codingstandards.cpp.Pointers
1818

1919
from CStyleCast cast, Type baseTypeFrom, Type baseTypeTo
2020
where

c/misra/src/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import cpp
1515
import codingstandards.c.misra
16-
import codingstandards.c.Pointers
16+
import codingstandards.cpp.Pointers
1717

1818
from CStyleCast cast, Type typeFrom, Type typeTo
1919
where

c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import cpp
1515
import codingstandards.c.misra
16-
import codingstandards.c.Pointers
16+
import codingstandards.cpp.Pointers
1717

1818
from Cast cast, VoidPointerType type, PointerToObjectType newType
1919
where

c/misra/src/rules/RULE-11-6/CastBetweenPointerToVoidAndArithmeticType.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import cpp
1515
import codingstandards.c.misra
16-
import codingstandards.c.Pointers
16+
import codingstandards.cpp.Pointers
1717

1818
from CStyleCast cast, Type typeFrom, Type typeTo
1919
where

c/misra/src/rules/RULE-11-7/CastBetweenPointerToObjectAndNonIntArithmeticType.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import cpp
1515
import codingstandards.c.misra
16-
import codingstandards.c.Pointers
16+
import codingstandards.cpp.Pointers
1717

1818
class MisraNonIntegerArithmeticType extends Type {
1919
MisraNonIntegerArithmeticType() {

c/misra/src/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import cpp
1414
import codingstandards.c.misra
15-
import codingstandards.c.Pointers
15+
import codingstandards.cpp.Pointers
1616
import codingstandards.cpp.Type
1717

1818
from Zero zero, Expr e, string type

c/misra/src/rules/RULE-21-15/MemcpyMemmoveMemcmpArgNotPointersToCompatibleTypes.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import cpp
1414
import codingstandards.c.misra
15-
import codingstandards.c.Pointers
15+
import codingstandards.cpp.Pointers
1616

1717
class MemCmpMoveCpy extends Function {
1818
// Couldn't extend BuiltInFunction because it misses `memcmp`

c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import cpp
1717
import codingstandards.c.misra
18-
import codingstandards.c.Pointers
18+
import codingstandards.cpp.Pointers
1919
import codingstandards.cpp.SideEffect
2020

2121
from Variable ptr, PointerOrArrayType type
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id cpp/autosar/do-not-pass-aliased-pointer-to-restrict-qualified-param
3+
* @name M0-2-1: Do not pass aliased pointers as parameters of functions where it is undefined behaviour for those pointers to overlap
4+
* @description Passing an aliased pointer to a conceptually restrict-qualified parameter is
5+
* undefined behavior.
6+
* @kind problem
7+
* @precision medium
8+
* @problem.severity error
9+
* @tags external/autosar/id/m0-2-1
10+
* correctness
11+
* external/autosar/allocated-target/implementation
12+
* external/autosar/enforcement/automated
13+
* external/autosar/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.cpp.autosar
18+
import codingstandards.cpp.rules.donotpassaliasedpointertorestrictqualifiedparam_shared.DoNotPassAliasedPointerToRestrictQualifiedParam_Shared
19+
20+
class DoNotPassAliasedPointerToRestrictQualifiedParamQuery extends DoNotPassAliasedPointerToRestrictQualifiedParam_SharedSharedQuery {
21+
DoNotPassAliasedPointerToRestrictQualifiedParamQuery() {
22+
this = RepresentationPackage::doNotPassAliasedPointerToRestrictQualifiedParamQuery()
23+
}
24+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparam_shared/DoNotPassAliasedPointerToRestrictQualifiedParam_Shared.ql

cpp/autosar/test/rules/M0-2-1/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ void internal_shift() {
5151
void separate_access() {
5252
UnionSecret_t hash1, hash2;
5353
hash2.diff.suffix = hash1.fnv.suffix; // COMPLIANT, different union.
54-
}
54+
}

cpp/common/src/codingstandards/cpp/Variable.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,17 @@ import semmle.code.cpp.PODType03
55
class ScalarVariable extends Variable {
66
ScalarVariable() { isScalarType03(this.getType()) }
77
}
8+
9+
/**
10+
* Returns the target variable of a `VariableAccess`.
11+
* If the access is a field access, then the target is the `Variable` of the qualifier.
12+
* If the access is an array access, then the target is the array base.
13+
*/
14+
Variable getAddressOfExprTargetBase(AddressOfExpr expr) {
15+
result = expr.getOperand().(ValueFieldAccess).getQualifier().(VariableAccess).getTarget()
16+
or
17+
not expr.getOperand() instanceof ValueFieldAccess and
18+
result = expr.getOperand().(VariableAccess).getTarget()
19+
or
20+
result = expr.getOperand().(ArrayExpr).getArrayBase().(VariableAccess).getTarget()
21+
}

0 commit comments

Comments
 (0)