Skip to content

Commit a845f38

Browse files
committed
IntegerOverflow: Exclude macro results
For the "constantintegerexpressionswraparound" query, exclude results in macros from third-party libraries which do not have any arguments, as they are (a) not controlled by the user (b) likely intended or false positives (such as UULONG_MAX).
1 parent d64b125 commit a845f38

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

c/common/test/rules/constantunsignedintegerexpressionswraparound/ConstantUnsignedIntegerExpressionsWrapAround.expected

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@
55
| test.c:25:7:25:18 | ... - ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
66
| test.c:26:7:26:17 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
77
| test.c:33:7:33:20 | ... - ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
8-
| test.c:34:7:34:16 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
98
| test.c:34:7:34:20 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
10-
| test.c:37:40:37:49 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
119
| test.c:40:7:40:19 | ... - ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1210
| test.c:41:7:41:19 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
13-
| test.c:46:7:46:17 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1411
| test.c:47:7:47:18 | ... - ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1512
| test.c:48:7:48:17 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
16-
| test.c:48:7:48:17 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |
1713
| test.c:53:20:53:31 | ... + ... | Use of a constant, unsigned, integer expression that over- or under-flows. |

cpp/common/src/codingstandards/cpp/Macro.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,16 @@ predicate isMacroInvocationLocation(MacroInvocation mi, File f, int startChar, i
7171

7272
/** A macro within the source location of this project. */
7373
class UserProvidedMacro extends Macro {
74-
UserProvidedMacro() { exists(this.getFile().getRelativePath()) }
74+
UserProvidedMacro() {
75+
exists(this.getFile().getRelativePath()) and
76+
// Exclude macros in our standard library header stubs for tests, because qltest sets the source
77+
// root to the qlpack root, which means our stubs all look like source files.
78+
//
79+
// This may affect "real" code as well, if it happens to be at this path, but given the name
80+
// I think it's likely that we'd want that to be the case anyway.
81+
not this.getFile().getRelativePath().substring(0, "includes/standard-library".length()) =
82+
"includes/standard-library"
83+
}
7584
}
7685

7786
/** A macro defined within a library used by this project. */

cpp/common/src/codingstandards/cpp/rules/constantunsignedintegerexpressionswraparound/ConstantUnsignedIntegerExpressionsWrapAround.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import cpp
77
import codingstandards.cpp.Customizations
8+
import codingstandards.cpp.Macro
89
import codingstandards.cpp.Exclusions
910
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1011

@@ -17,5 +18,21 @@ query predicate problems(BinaryArithmeticOperation bao, string message) {
1718
bao.isConstant() and
1819
bao.getUnderlyingType().(IntegralType).isUnsigned() and
1920
convertedExprMightOverflow(bao) and
21+
// Exclude expressions generated from macro invocations of argument-less macros in third party
22+
// code. This is because these are not under the control of the developer. Macros with arguments
23+
// are not excluded, so that we can report cases where the argument provided by the developer
24+
// wraps around (this may also report cases where the macro itself contains a wrapping expression,
25+
// but we cannot distinguish these cases because we don't know which generated expressions are
26+
// affected by which arguments).
27+
//
28+
// This addresses a false positive in the test cases on UULONG_MAX, which is reported in MUSL
29+
// because it is defined as (2ULL*LLONG_MAX+1), which is a constant integer expression, and
30+
// although it doesn't wrap in practice, our range analysis loses precision at the top end of the
31+
// unsigned long long range so incorrectly assumes it can wrap.
32+
not exists(LibraryMacro m, MacroInvocation mi |
33+
mi = m.getAnInvocation() and
34+
mi.getAnExpandedElement() = bao and
35+
not exists(mi.getUnexpandedArgument(_))
36+
) and
2037
message = "Use of a constant, unsigned, integer expression that over- or under-flows."
2138
}

0 commit comments

Comments
 (0)