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/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. 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..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 @@ -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: 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: like char*, std::byte* is a generic pointer type, + // so assume that it is really an int*. + return reinterpret_cast(p + 1); +}