Skip to content

[Bitcode] Fix a signed integer overflow in BitstreamWriter.h #75213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

MaggieYingYi
Copy link
Contributor

UBSAN finds undefined behavior (signed integer overflow) in BitstreamWriter.h line 242 and 258.

To reproduce the issue, I have copied the functions EmitVBR and EmitVBR64 into a simple code main.cpp:

$ cat main.cpp
#include <cassert>
#include <cstdint>

void Emit(uint32_t Val, unsigned NumBits) {
  assert(NumBits && NumBits <= 32 && "Invalid value size!");
  assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
}

void EmitVBR(uint32_t Val, unsigned NumBits) {
  assert(NumBits <= 32 && "Too many bits to emit!");
  uint32_t Threshold = 1U << (NumBits-1);

  // Emit the bits with VBR encoding, NumBits-1 bits at a time.
  while (Val >= Threshold) {
    Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
    Val >>= NumBits-1;
  }

  Emit(Val, NumBits);
}

void EmitVBR64(uint64_t Val, unsigned NumBits) {
  assert(NumBits <= 32 && "Too many bits to emit!");
  if ((uint32_t)Val == Val)
    return EmitVBR((uint32_t)Val, NumBits);

  uint32_t Threshold = 1U << (NumBits-1);

  // Emit the bits with VBR encoding, NumBits-1 bits at a time.
  while (Val >= Threshold) {
    Emit(((uint32_t)Val & ((1 << (NumBits - 1)) - 1)) | (1 << (NumBits - 1)),
         NumBits);
    Val >>= NumBits-1;
  }

  Emit((uint32_t)Val, NumBits);
}

int main() {
  unsigned NumBits= 32;
  uint32_t UInt32 = 4294967295;
  uint64_t UInt64 = 1844674407370955161;
 
  EmitVBR64(UInt32, NumBits);
  EmitVBR64(UInt64, NumBits);
  return 0;
}

Compile the code using

To reproduce this issue, build main.cpp with the -fsanitize=undefined option:

clang++.exe -fsanitize=undefined main.cpp -o main.exe

Run the main.exe:

$ main.exe
main.cpp:15:36: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior main.cpp:15:36 in
main.cpp:31:49: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior main.cpp:31:49 in

The issue could be fixed by using 1U instead of 1.

@MaggieYingYi
Copy link
Contributor Author

gentle pining ...

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nikic nikic changed the title Fix a signed integer overflow in BitstreamWriter.h which is found by UBSAN. [Bitcode] Fix a signed integer overflow in BitstreamWriter.h Jan 2, 2024
@MaggieYingYi
Copy link
Contributor Author

LGTM

Thanks.

@MaggieYingYi
Copy link
Contributor Author

Committed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants