From 73542aca3b9b57b0a4a09c127a34f62fc07604b1 Mon Sep 17 00:00:00 2001 From: jketema <93738568+jketema@users.noreply.github.com> Date: Thu, 29 Oct 2026 11:10:39 +0000 Subject: [PATCH 1/3] Add std::byte pointer scaling regression tests Reproduce #22929 with int-pointer arithmetic from std::byte storage using C-style casts and reinterpret_cast. Record the current false positives alongside the existing char-pointer coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../IncorrectPointerScaling.expected | 2 ++ .../semmle/IncorrectPointerScaling/test.cpp | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected index 3ea7d23e5339..ae368672a2d3 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected @@ -1,3 +1,5 @@ | test.cpp:50:19:50:19 | p | This pointer might have type $@ (size 8), but this pointer arithmetic is done with type int * (size 4). | test.cpp:45:11:45:11 | test.cpp:45:11:45:11 | double | | test.cpp:94:18:94:18 | x | This pointer might have type $@ (size 4), but this pointer arithmetic is done with type short * (size 2). | test.cpp:88:21:88:21 | test.cpp:88:21:88:21 | int | | test.cpp:130:27:130:29 | arr | This pointer might have type $@ (size 4), but this pointer arithmetic is done with type short * (size 2). | test.cpp:128:16:128:18 | test.cpp:128:16:128:18 | int | +| test.cpp:160:24:160:24 | p | This pointer might have type $@ (size 1), but this pointer arithmetic is done with type int * (size 4). | test.cpp:155:14:155:14 | test.cpp:155:14:155:14 | byte | +| test.cpp:169:39:169:39 | p | This pointer might have type $@ (size 1), but this pointer arithmetic is done with type int * (size 4). | test.cpp:164:14:164:14 | test.cpp:164:14:164:14 | byte | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp index 9f6b046a90bd..7a5d189ff370 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp @@ -146,3 +146,25 @@ int test18(int i) { // BAD: the pointer arithmetic uses type char*, so the offset is not scaled by sizeof(int). return *(int *)(charPointer + i); // $ Alert[cpp/incorrect-pointer-scaling-char] } + +namespace std { +enum class byte : unsigned char {}; +} + +std::byte* test19( + std::byte *x +) { + int *p = (int*)x; + // GOOD [FALSE POSITIVE cpp/suspicious-pointer-scaling]: like char*, std::byte* + // is a generic pointer type, so assume that it is really an int*. + return (std::byte *)(p + 1); // $ Alert[cpp/suspicious-pointer-scaling] +} + +std::byte* test20( + std::byte *x +) { + int *p = reinterpret_cast(x); + // GOOD [FALSE POSITIVE cpp/suspicious-pointer-scaling]: like char*, std::byte* + // is a generic pointer type, so assume that it is really an int*. + return reinterpret_cast(p + 1); // $ Alert[cpp/suspicious-pointer-scaling] +} From ebae47dcd16bf9f3cbcb235a4f0877f3acebf14c Mon Sep 17 00:00:00 2001 From: jketema <93738568+jketema@users.noreply.github.com> Date: Thu, 29 Oct 2026 11:13:13 +0000 Subject: [PATCH 2/3] Exclude std::byte buffers from suspicious pointer scaling Treat std::byte source pointers like char and void buffers when checking pointer scaling, avoiding false positives for intentional typed indexing. Match only the standard byte enum and update both cast-style tests to expect no alerts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Security/CWE/CWE-468/IncorrectPointerScaling.ql | 3 ++- .../IncorrectPointerScaling.expected | 2 -- .../CWE-468/semmle/IncorrectPointerScaling/test.cpp | 12 ++++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql b/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql index a8f71c4e1d0d..49ab69ff2490 100644 --- a/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql +++ b/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql @@ -22,11 +22,12 @@ where destBase = baseType(destType) and destBase.getSize() != sourceBase.getSize() and not dest.isInMacroExpansion() and - // If the source type is a `char*` or `void*` then don't + // If the source type is a `char*`, `void*` or `std::byte*` then don't // produce a result, because it is likely to be a false // positive. not sourceBase instanceof CharType and not sourceBase instanceof VoidType and + not sourceBase.(Enum).hasQualifiedName("std", "byte") and // Low-level pointer tricks often involve casting a struct pointer to a // char pointer, then accessing it at byte offsets. For example, this can // be necessary in order to resume an interrupted `write(2)`. diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected index ae368672a2d3..3ea7d23e5339 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/IncorrectPointerScaling.expected @@ -1,5 +1,3 @@ | test.cpp:50:19:50:19 | p | This pointer might have type $@ (size 8), but this pointer arithmetic is done with type int * (size 4). | test.cpp:45:11:45:11 | test.cpp:45:11:45:11 | double | | test.cpp:94:18:94:18 | x | This pointer might have type $@ (size 4), but this pointer arithmetic is done with type short * (size 2). | test.cpp:88:21:88:21 | test.cpp:88:21:88:21 | int | | test.cpp:130:27:130:29 | arr | This pointer might have type $@ (size 4), but this pointer arithmetic is done with type short * (size 2). | test.cpp:128:16:128:18 | test.cpp:128:16:128:18 | int | -| test.cpp:160:24:160:24 | p | This pointer might have type $@ (size 1), but this pointer arithmetic is done with type int * (size 4). | test.cpp:155:14:155:14 | test.cpp:155:14:155:14 | byte | -| test.cpp:169:39:169:39 | p | This pointer might have type $@ (size 1), but this pointer arithmetic is done with type int * (size 4). | test.cpp:164:14:164:14 | test.cpp:164:14:164:14 | byte | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp index 7a5d189ff370..1011a5ee8fb2 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-468/semmle/IncorrectPointerScaling/test.cpp @@ -155,16 +155,16 @@ std::byte* test19( std::byte *x ) { int *p = (int*)x; - // GOOD [FALSE POSITIVE cpp/suspicious-pointer-scaling]: like char*, std::byte* - // is a generic pointer type, so assume that it is really an int*. - return (std::byte *)(p + 1); // $ Alert[cpp/suspicious-pointer-scaling] + // GOOD: like char*, std::byte* is a generic pointer type, + // so assume that it is really an int*. + return (std::byte *)(p + 1); } std::byte* test20( std::byte *x ) { int *p = reinterpret_cast(x); - // GOOD [FALSE POSITIVE cpp/suspicious-pointer-scaling]: like char*, std::byte* - // is a generic pointer type, so assume that it is really an int*. - return reinterpret_cast(p + 1); // $ Alert[cpp/suspicious-pointer-scaling] + // GOOD: like char*, std::byte* is a generic pointer type, + // so assume that it is really an int*. + return reinterpret_cast(p + 1); } From e701d22ddf58c9d916f12b69ea949a10b7d8b574 Mon Sep 17 00:00:00 2001 From: jketema <93738568+jketema@users.noreply.github.com> Date: Thu, 29 Oct 2026 11:33:00 +0000 Subject: [PATCH 3/3] Document std::byte pointer scaling fix Add a minor analysis note for the reduced false positives in suspicious pointer scaling when indexing std::byte buffers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../2026-10-29-suspicious-pointer-scaling-byte.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2026-10-29-suspicious-pointer-scaling-byte.md diff --git a/cpp/ql/src/change-notes/2026-10-29-suspicious-pointer-scaling-byte.md b/cpp/ql/src/change-notes/2026-10-29-suspicious-pointer-scaling-byte.md new file mode 100644 index 000000000000..a8c4c305b094 --- /dev/null +++ b/cpp/ql/src/change-notes/2026-10-29-suspicious-pointer-scaling-byte.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `cpp/suspicious-pointer-scaling` query no longer reports false positives for intentional pointer arithmetic from `std::byte*` buffers.