Skip to content

Commit c6b2f25

Browse files
committed
debug/elf: prevent out-of-bounds access in applyRelocations
When parsing DWARF information, the applyRelocations functions are called to process relocations. A malformed ELF file can contain a relocation entry with an offset that points outside the destination buffer. This leads to an out-of-bounds access when attempting to apply the relocation, causing a panic. This change adds bounds checks to all 'applyRelocations<ARCH>' functions to validate the offset before writing. If an offset is invalid, the relocation entry is skipped, preventing the panic when parsing a malformed ELF file. Fixes #75516 Change-Id: I3a1662398a981977d6cbacfa47c40707ddd87b37
1 parent ef05b66 commit c6b2f25

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

src/debug/elf/file.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -830,13 +830,13 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
830830

831831
switch t {
832832
case R_X86_64_64:
833-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
833+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
834834
continue
835835
}
836836
val64 := sym.Value + uint64(rela.Addend)
837837
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
838838
case R_X86_64_32:
839-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
839+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
840840
continue
841841
}
842842
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -872,7 +872,7 @@ func (f *File) applyRelocations386(dst []byte, rels []byte) error {
872872
sym := &symbols[symNo-1]
873873

874874
if t == R_386_32 {
875-
if rel.Off+4 >= uint32(len(dst)) {
875+
if rel.Off+4 >= uint32(len(dst)) || rel.Off+4 < rel.Off {
876876
continue
877877
}
878878
val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
@@ -910,7 +910,7 @@ func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
910910

911911
switch t {
912912
case R_ARM_ABS32:
913-
if rel.Off+4 >= uint32(len(dst)) {
913+
if rel.Off+4 >= uint32(len(dst)) || rel.Off+4 < rel.Off {
914914
continue
915915
}
916916
val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
@@ -955,13 +955,13 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
955955

956956
switch t {
957957
case R_AARCH64_ABS64:
958-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
958+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
959959
continue
960960
}
961961
val64 := sym.Value + uint64(rela.Addend)
962962
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
963963
case R_AARCH64_ABS32:
964-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
964+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
965965
continue
966966
}
967967
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -1001,7 +1001,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
10011001

10021002
switch t {
10031003
case R_PPC_ADDR32:
1004-
if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
1004+
if rela.Off+4 >= uint32(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
10051005
continue
10061006
}
10071007
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -1041,13 +1041,13 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
10411041

10421042
switch t {
10431043
case R_PPC64_ADDR64:
1044-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
1044+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
10451045
continue
10461046
}
10471047
val64 := sym.Value + uint64(rela.Addend)
10481048
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
10491049
case R_PPC64_ADDR32:
1050-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
1050+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
10511051
continue
10521052
}
10531053
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -1084,7 +1084,7 @@ func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error {
10841084

10851085
switch t {
10861086
case R_MIPS_32:
1087-
if rel.Off+4 >= uint32(len(dst)) {
1087+
if rel.Off+4 >= uint32(len(dst)) || rel.Off+4 < rel.Off {
10881088
continue
10891089
}
10901090
val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
@@ -1132,13 +1132,13 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
11321132

11331133
switch t {
11341134
case R_MIPS_64:
1135-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
1135+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
11361136
continue
11371137
}
11381138
val64 := sym.Value + uint64(rela.Addend)
11391139
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
11401140
case R_MIPS_32:
1141-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
1141+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
11421142
continue
11431143
}
11441144
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -1180,13 +1180,13 @@ func (f *File) applyRelocationsLOONG64(dst []byte, rels []byte) error {
11801180

11811181
switch t {
11821182
case R_LARCH_64:
1183-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
1183+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
11841184
continue
11851185
}
11861186
val64 := sym.Value + uint64(rela.Addend)
11871187
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
11881188
case R_LARCH_32:
1189-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
1189+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
11901190
continue
11911191
}
11921192
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -1226,13 +1226,13 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
12261226

12271227
switch t {
12281228
case R_RISCV_64:
1229-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
1229+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
12301230
continue
12311231
}
12321232
val64 := sym.Value + uint64(rela.Addend)
12331233
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
12341234
case R_RISCV_32:
1235-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
1235+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
12361236
continue
12371237
}
12381238
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -1272,13 +1272,13 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
12721272

12731273
switch t {
12741274
case R_390_64:
1275-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
1275+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
12761276
continue
12771277
}
12781278
val64 := sym.Value + uint64(rela.Addend)
12791279
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
12801280
case R_390_32:
1281-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
1281+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
12821282
continue
12831283
}
12841284
val32 := uint32(sym.Value) + uint32(rela.Addend)
@@ -1318,13 +1318,13 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
13181318

13191319
switch t {
13201320
case R_SPARC_64, R_SPARC_UA64:
1321-
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
1321+
if rela.Off+8 >= uint64(len(dst)) || rela.Off+8 < rela.Off || rela.Addend < 0 {
13221322
continue
13231323
}
13241324
val64 := sym.Value + uint64(rela.Addend)
13251325
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
13261326
case R_SPARC_32, R_SPARC_UA32:
1327-
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
1327+
if rela.Off+4 >= uint64(len(dst)) || rela.Off+4 < rela.Off || rela.Addend < 0 {
13281328
continue
13291329
}
13301330
val32 := uint32(sym.Value) + uint32(rela.Addend)

0 commit comments

Comments
 (0)