diff options
| author | sdawson-nvidia <115184855+sdawson-nvidia@users.noreply.github.com> | 2022-10-07 14:59:31 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-07 15:59:31 -0400 |
| commit | 34ba10d1b883700992f34c68ed72f659d3644461 (patch) | |
| tree | c4388fbcacabb1b2fb17aadc60d9f919347d3066 /source/core/slang-byte-encode-util.cpp | |
| parent | 88663a6815cb411b0c81e6c28e7f1c7643659c30 (diff) | |
Prevent out of bounds access by unaligned access in decodeLiteUInt32 (#2435)
This prevents memory tools like gflags causing an exception on the out of bound access.
Co-authored-by: jsmall-nvidia <jsmall@nvidia.com>
Diffstat (limited to 'source/core/slang-byte-encode-util.cpp')
| -rw-r--r-- | source/core/slang-byte-encode-util.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/source/core/slang-byte-encode-util.cpp b/source/core/slang-byte-encode-util.cpp index 32eb96a29..c542cc265 100644 --- a/source/core/slang-byte-encode-util.cpp +++ b/source/core/slang-byte-encode-util.cpp @@ -256,20 +256,30 @@ static const uint32_t s_unalignedUInt32Mask[5] = int numBytesRemaining = b0 - kLiteCut2 + 2 - 1; #if SLANG_BYTE_ENCODE_USE_UNALIGNED_ACCESS - const uint32_t mask = s_unalignedUInt32Mask[numBytesRemaining]; - //const uint32_t mask = ~(uint32_t(0xffffff00) << ((numBytesRemaining - 1) * 8)); - const uint32_t value = (*(const uint32_t*)encodeIn) & mask; -#else - // This works on all cpus although slower - uint32_t value = encodeIn[0]; - switch (numBytesRemaining) + uint32_t value = 0; + // Do not use unaligned access for the last two values, + // (3rd last is safe because this value will have at least 2 bytes, followed by at worst two 1-byte values) + // otherwise we can access outside the bounds of the encoded array + // This prevents memory validation tools from causing an exception here + if (i < numValues - 2) + { + const uint32_t mask = s_unalignedUInt32Mask[numBytesRemaining]; + //const uint32_t mask = ~(uint32_t(0xffffff00) << ((numBytesRemaining - 1) * 8)); + value = (*(const uint32_t*)encodeIn) & mask; + } + else +#endif { + // This works on all cpus although slower + value = encodeIn[0]; + switch (numBytesRemaining) + { case 4: value |= uint32_t(encodeIn[3]) << 24; /* fall thru */ case 3: value |= uint32_t(encodeIn[2]) << 16; /* fall thru */ case 2: value |= uint32_t(encodeIn[1]) << 8; /* fall thru */ case 1: break; + } } -#endif valuesOut[i] = value; encodeIn += numBytesRemaining; } |
