aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/MachOObjectFile.cpp
diff options
context:
space:
mode:
authorZixu Wang <9819235+zixu-w@users.noreply.github.com>2024-05-08 18:53:15 -0700
committerGitHub <noreply@github.com>2024-05-08 18:53:15 -0700
commitb910bebc300dafb30569cecc3017b446ea8eafa0 (patch)
tree161baf5e8348f866053eabe037ef4322a920546e /llvm/lib/Object/MachOObjectFile.cpp
parentea126aebdc9d8205016f355d85dbf1c15f2f4b28 (diff)
downloadllvm-b910bebc300dafb30569cecc3017b446ea8eafa0.zip
llvm-b910bebc300dafb30569cecc3017b446ea8eafa0.tar.gz
llvm-b910bebc300dafb30569cecc3017b446ea8eafa0.tar.bz2
[llvm][MachO] Fix integer truncation in rebase/bind parsing (#89337)
`Count` and `Skip` should use `uint64_t` as they are encoded/decoded using 64-bit ULEB128. In `*_OPCODE_DO_*_ULEB_TIMES_SKIPPING_ULEB`, `Skip` could be encoded as a two's complement for moving `SegmentOffset` backwards. Having a 32-bit `Skip` truncates the encoded value and leads to a malformed `AdvanceAmount` and invalid `SegmentOffset` that extends past valid sections.
Diffstat (limited to 'llvm/lib/Object/MachOObjectFile.cpp')
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp20
1 files changed, 10 insertions, 10 deletions
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 06186ad..ef390ce 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -3515,7 +3515,7 @@ void MachORebaseEntry::moveNext() {
uint8_t Byte = *Ptr++;
uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK;
uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK;
- uint32_t Count, Skip;
+ uint64_t Count, Skip;
const char *error = nullptr;
switch (Opcode) {
case MachO::REBASE_OPCODE_DONE:
@@ -3854,7 +3854,7 @@ void MachOBindEntry::moveNext() {
uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK;
int8_t SignExtended;
const uint8_t *SymStart;
- uint32_t Count, Skip;
+ uint64_t Count, Skip;
const char *error = nullptr;
switch (Opcode) {
case MachO::BIND_OPCODE_DONE:
@@ -4384,18 +4384,18 @@ BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) {
// that fully contains a pointer at that location. Multiple fixups in a bind
// (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
// be tested via the Count and Skip parameters.
-const char * BindRebaseSegInfo::checkSegAndOffsets(int32_t SegIndex,
- uint64_t SegOffset,
- uint8_t PointerSize,
- uint32_t Count,
- uint32_t Skip) {
+const char *BindRebaseSegInfo::checkSegAndOffsets(int32_t SegIndex,
+ uint64_t SegOffset,
+ uint8_t PointerSize,
+ uint64_t Count,
+ uint64_t Skip) {
if (SegIndex == -1)
return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB";
if (SegIndex >= MaxSegIndex)
return "bad segIndex (too large)";
- for (uint32_t i = 0; i < Count; ++i) {
- uint32_t Start = SegOffset + i * (PointerSize + Skip);
- uint32_t End = Start + PointerSize;
+ for (uint64_t i = 0; i < Count; ++i) {
+ uint64_t Start = SegOffset + i * (PointerSize + Skip);
+ uint64_t End = Start + PointerSize;
bool Found = false;
for (const SectionInfo &SI : Sections) {
if (SI.SegmentIndex != SegIndex)