Skip to content

Commit d0e7ed3

Browse files
cdotstoutzarvox
andauthored
[spirv-remap] Fix undefined behavior in hashing (KhronosGroup#2403)
There's a statement that intends to generate a 32-bit hashcode, but due to integer promotion, the intermediate values can trigger signed integer overflow, which is undefined behavior. To avoid this, cast at least one operand to unsigned int before multiplying, which will cause the result to be promoted to unsigned int instead of signed int. With this patch, I'm able to build core for qemu-x64 with host_asan-ubsan. Fixed: 60128 Change-Id: Idd644e534116bf29dca8013936ac39901bbe68fc Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/glslang/+/428254 Reviewed-by: John Bauman <[email protected]> Co-authored-by: Drew Fisher <[email protected]>
1 parent 1815d86 commit d0e7ed3

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

SPIRV/SPVRemapper.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,15 @@ namespace spv {
830830
[&](spv::Id& id) {
831831
if (thisOpCode != spv::OpNop) {
832832
++idCounter;
833-
const std::uint32_t hashval = opCounter[thisOpCode] * thisOpCode * 50047 + idCounter + fnId * 117;
833+
const std::uint32_t hashval =
834+
// Explicitly cast operands to unsigned int to avoid integer
835+
// promotion to signed int followed by integer overflow,
836+
// which would result in undefined behavior.
837+
static_cast<unsigned int>(opCounter[thisOpCode])
838+
* thisOpCode
839+
* 50047
840+
+ idCounter
841+
+ static_cast<unsigned int>(fnId) * 117;
834842

835843
if (isOldIdUnmapped(id))
836844
localId(id, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));

0 commit comments

Comments
 (0)