diff --git a/cpp/ql/lib/change-notes/2023-03-21-buffer-access.md b/cpp/ql/lib/change-notes/2023-03-21-buffer-access.md new file mode 100644 index 00000000000..7b2b6bad0dc --- /dev/null +++ b/cpp/ql/lib/change-notes/2023-03-21-buffer-access.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `BufferAccess` library (`semmle.code.cpp.security.BufferAccess`) no longer matches buffer accesses inside unevaluated contexts (such as inside `sizeof` or `decltype` expressions). As a result, queries using this library may see fewer false positives. \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll b/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll index faeb859506d..e52babcfe2e 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll @@ -14,6 +14,8 @@ int getPointedSize(Type t) { * BufferWrite differ. */ abstract class BufferAccess extends Expr { + BufferAccess() { not this.isUnevaluated() } + abstract string getName(); /** diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql index 962d2ee89b0..13a4fb6bcb7 100644 --- a/cpp/ql/src/Critical/OverflowStatic.ql +++ b/cpp/ql/src/Critical/OverflowStatic.ql @@ -22,7 +22,8 @@ import LoopBounds private predicate staticBufferBase(VariableAccess access, Variable v) { v.getType().(ArrayType).getBaseType() instanceof CharType and access = v.getAnAccess() and - not memberMayBeVarSize(_, v) + not memberMayBeVarSize(_, v) and + not access.isUnevaluated() } predicate staticBuffer(VariableAccess access, Variable v, int size) { diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp index 01a4a0adaef..deeb70ffd57 100644 --- a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp +++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.cpp @@ -56,3 +56,8 @@ void f3() { } } } + +int unevaluated_test() { + char buffer[100]; + return sizeof(buffer) / sizeof(buffer[101]); // GOOD +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp index 6dbbcdd4b3e..90f942023c4 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/tests.cpp @@ -603,6 +603,11 @@ void test22(bool b, const char* source) { memcpy(dest, source, n); // GOOD } +int test23() { + char buffer[100]; + return sizeof(buffer) / sizeof(buffer[101]); // GOOD +} + int tests_main(int argc, char *argv[]) { long long arr17[19]; @@ -627,6 +632,7 @@ int tests_main(int argc, char *argv[]) test20(); test21(argc == 0); test22(argc == 0, argv[0]); + test23(); return 0; }