Skip to content

Commit 74f8145

Browse files
authored
Add files via upload
1 parent 3d1f4d5 commit 74f8145

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
...
2+
vUnsignedLong = (unsigned long)(vUnsignedInt*vUnsignedInt); // BAD
3+
...
4+
vUnsignedLong = ((unsigned long)vUnsignedInt*vUnsignedInt); // GOOD
5+
...
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Searching for places where data type conversion occurs late and does not affect the computational result.</p>
7+
8+
9+
</overview>
10+
11+
<example>
12+
<p>The following example demonstrates erroneous and fixed methods for working with type conversion.</p>
13+
<sample src="DangerousUseOfTransformationAfterOperation.cpp" />
14+
15+
</example>
16+
<references>
17+
18+
<li>
19+
CERT C Coding Standard:
20+
<a href="https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap">INT30-C. Ensure that unsigned integer operations do not wrap</a>.
21+
</li>
22+
23+
</references>
24+
</qhelp>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* @name Dangerous use of transformation after operation.
3+
* @description By using the transformation after the operation, you are doing a pointless and dangerous action.
4+
* @kind problem
5+
* @id cpp/dangerous-use-of-transformation-after-operation.
6+
* @problem.severity warning
7+
* @precision medium
8+
* @tags correctness
9+
* security
10+
* external/cwe/cwe-190
11+
*/
12+
13+
import cpp
14+
15+
/** Returns the number of the expression in the function call arguments. */
16+
int argumentPosition(FunctionCall fc, Expr exp, int n) {
17+
n in [0 .. fc.getNumberOfArguments() - 1] and
18+
fc.getArgument(n) = exp and
19+
result = n
20+
}
21+
22+
/** Holds if a nonsensical type conversion situation is found. */
23+
predicate conversionDoneLate(MulExpr mexp, Expr e1, Expr e2) {
24+
mexp.getConversion().hasExplicitConversion() and
25+
mexp.getConversion() instanceof ParenthesisExpr and
26+
mexp.getConversion().getConversion() instanceof CStyleCast and
27+
mexp.getConversion().getConversion().getType().getSize() > mexp.getType().getSize() and
28+
mexp.getConversion().getConversion().getType().getSize() > e2.getType().getSize() and
29+
mexp.getConversion().getConversion().getType().getSize() > e1.getType().getSize() and
30+
exists(Expr e0 |
31+
e0.(AssignExpr).getRValue() = mexp.getParent*() and
32+
e0.(AssignExpr).getLValue().getType().getSize() =
33+
mexp.getConversion().getConversion().getType().getSize()
34+
or
35+
mexp.getEnclosingElement().(ComparisonOperation).hasOperands(mexp, e0) and
36+
e0.getType().getSize() = mexp.getConversion().getConversion().getType().getSize()
37+
or
38+
e0.(FunctionCall)
39+
.getTarget()
40+
.getParameter(argumentPosition(e0.(FunctionCall), mexp, _))
41+
.getType()
42+
.getSize() = mexp.getConversion().getConversion().getType().getSize()
43+
)
44+
}
45+
46+
/** Holds if the situation of a possible signed overflow used in pointer arithmetic is found. */
47+
predicate signSmallerWithEqualSizes(MulExpr mexp, Expr e1, Expr e2) {
48+
mexp.getConversion+().getUnderlyingType().getSize() = e1.getUnderlyingType().getSize() and
49+
(
50+
e2.isConstant() or
51+
mexp.getConversion+().getUnderlyingType().getSize() = e2.getUnderlyingType().getSize()
52+
) and
53+
mexp.getConversion+().getUnderlyingType().getSize() = e1.getUnderlyingType().getSize() and
54+
exists(AssignExpr ae |
55+
ae.getRValue() = mexp.getParent*() and
56+
ae.getRValue().getUnderlyingType().(IntegralType).isUnsigned() and
57+
ae.getLValue().getUnderlyingType().(IntegralType).isSigned() and
58+
(
59+
not exists(DivExpr de | mexp.getParent*() = de)
60+
or
61+
exists(DivExpr de, Expr ec |
62+
e2.isConstant() and
63+
de.hasOperands(mexp.getParent*(), ec) and
64+
ec.isConstant() and
65+
e2.getValue().toInt() > ec.getValue().toInt()
66+
)
67+
) and
68+
exists(PointerAddExpr pa |
69+
ae.getASuccessor+() = pa and
70+
pa.getAnOperand().(VariableAccess).getTarget() = ae.getLValue().(VariableAccess).getTarget()
71+
)
72+
)
73+
}
74+
75+
from MulExpr mexp, string msg
76+
where
77+
exists(Expr e1, Expr e2 |
78+
mexp.hasOperands(e1, e2) and
79+
not e1.isConstant() and
80+
not e1.hasConversion() and
81+
not e1.hasConversion() and
82+
(
83+
e2.isConstant() or
84+
not e2.hasConversion()
85+
) and
86+
(
87+
conversionDoneLate(mexp, e1, e2) and
88+
msg = "this transformation is applied after multiplication"
89+
or
90+
signSmallerWithEqualSizes(mexp, e1, e2) and
91+
msg = "possible signed overflow followed by offset of the pointer out of bounds"
92+
)
93+
)
94+
select mexp, msg

0 commit comments

Comments
 (0)