Skip to content

Commit 1082e23

Browse files
committed
cmd/link/internal/ld: stricter object file decoding
Instead of silently truncating integers to their expected range, check that they're within range and emit errors if not. Intended to help narrow down the cause of issue #11617. Change-Id: Ia7b577270f8438ca7479262702371e26277f1ea7 Reviewed-on: https://go-review.googlesource.com/12050 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 6a90b1d commit 1082e23

File tree

1 file changed

+59
-27
lines changed

1 file changed

+59
-27
lines changed

src/cmd/link/internal/ld/objfile.go

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -164,22 +164,22 @@ func readsym(ctxt *Link, f *obj.Biobuf, pkg string, pn string) {
164164
if obj.Bgetc(f) != 0xfe {
165165
log.Fatalf("readsym out of sync")
166166
}
167-
t := int(rdint(f))
167+
t := rdint(f)
168168
name := expandpkg(rdstring(f), pkg)
169-
v := int(rdint(f))
169+
v := rdint(f)
170170
if v != 0 && v != 1 {
171171
log.Fatalf("invalid symbol version %d", v)
172172
}
173-
flags := int(rdint(f))
173+
flags := rdint(f)
174174
dupok := flags & 1
175175
local := false
176176
if flags&2 != 0 {
177177
local = true
178178
}
179-
size := int(rdint(f))
179+
size := rdint(f)
180180
typ := rdsym(ctxt, f, pkg)
181181
data := rddata(f)
182-
nreloc := int(rdint(f))
182+
nreloc := rdint(f)
183183

184184
if v != 0 {
185185
v = ctxt.Version
@@ -241,11 +241,11 @@ overwrite:
241241
var r *Reloc
242242
for i := 0; i < nreloc; i++ {
243243
r = &s.R[i]
244-
r.Off = int32(rdint(f))
245-
r.Siz = uint8(rdint(f))
246-
r.Type = int32(rdint(f))
247-
r.Add = rdint(f)
248-
rdint(f) // Xadd, ignored
244+
r.Off = rdint32(f)
245+
r.Siz = rduint8(f)
246+
r.Type = rdint32(f)
247+
r.Add = rdint64(f)
248+
rdint64(f) // Xadd, ignored
249249
r.Sym = rdsym(ctxt, f, pkg)
250250
rdsym(ctxt, f, pkg) // Xsym, ignored
251251
}
@@ -260,19 +260,19 @@ overwrite:
260260
}
261261

262262
if s.Type == obj.STEXT {
263-
s.Args = int32(rdint(f))
264-
s.Locals = int32(rdint(f))
265-
s.Nosplit = uint8(rdint(f))
266-
v := int(rdint(f))
263+
s.Args = rdint32(f)
264+
s.Locals = rdint32(f)
265+
s.Nosplit = rduint8(f)
266+
v := rdint(f)
267267
s.Leaf = uint8(v & 1)
268268
s.Cfunc = uint8(v & 2)
269-
n := int(rdint(f))
269+
n := rdint(f)
270270
var a *Auto
271271
for i := 0; i < n; i++ {
272272
a = new(Auto)
273273
a.Asym = rdsym(ctxt, f, pkg)
274-
a.Aoffset = int32(rdint(f))
275-
a.Name = int16(rdint(f))
274+
a.Aoffset = rdint32(f)
275+
a.Name = rdint16(f)
276276
a.Gotype = rdsym(ctxt, f, pkg)
277277
a.Link = s.Autom
278278
s.Autom = a
@@ -283,23 +283,23 @@ overwrite:
283283
pc.Pcsp.P = rddata(f)
284284
pc.Pcfile.P = rddata(f)
285285
pc.Pcline.P = rddata(f)
286-
n = int(rdint(f))
286+
n = rdint(f)
287287
pc.Pcdata = make([]Pcdata, n)
288288
pc.Npcdata = n
289289
for i := 0; i < n; i++ {
290290
pc.Pcdata[i].P = rddata(f)
291291
}
292-
n = int(rdint(f))
292+
n = rdint(f)
293293
pc.Funcdata = make([]*LSym, n)
294294
pc.Funcdataoff = make([]int64, n)
295295
pc.Nfuncdata = n
296296
for i := 0; i < n; i++ {
297297
pc.Funcdata[i] = rdsym(ctxt, f, pkg)
298298
}
299299
for i := 0; i < n; i++ {
300-
pc.Funcdataoff[i] = rdint(f)
300+
pc.Funcdataoff[i] = rdint64(f)
301301
}
302-
n = int(rdint(f))
302+
n = rdint(f)
303303
pc.File = make([]*LSym, n)
304304
pc.Nfile = n
305305
for i := 0; i < n; i++ {
@@ -374,7 +374,7 @@ overwrite:
374374
}
375375
}
376376

377-
func rdint(f *obj.Biobuf) int64 {
377+
func rdint64(f *obj.Biobuf) int64 {
378378
var c int
379379

380380
uv := uint64(0)
@@ -392,15 +392,47 @@ func rdint(f *obj.Biobuf) int64 {
392392
return int64(uv>>1) ^ (int64(uint64(uv)<<63) >> 63)
393393
}
394394

395+
func rdint(f *obj.Biobuf) int {
396+
n := rdint64(f)
397+
if int64(int(n)) != n {
398+
log.Panicf("%v out of range for int", n)
399+
}
400+
return int(n)
401+
}
402+
403+
func rdint32(f *obj.Biobuf) int32 {
404+
n := rdint64(f)
405+
if int64(int32(n)) != n {
406+
log.Panicf("%v out of range for int32", n)
407+
}
408+
return int32(n)
409+
}
410+
411+
func rdint16(f *obj.Biobuf) int16 {
412+
n := rdint64(f)
413+
if int64(int16(n)) != n {
414+
log.Panicf("%v out of range for int16", n)
415+
}
416+
return int16(n)
417+
}
418+
419+
func rduint8(f *obj.Biobuf) uint8 {
420+
n := rdint64(f)
421+
if int64(uint8(n)) != n {
422+
log.Panicf("%v out of range for uint8", n)
423+
}
424+
return uint8(n)
425+
}
426+
395427
func rdstring(f *obj.Biobuf) string {
396-
n := rdint(f)
428+
n := rdint64(f)
397429
p := make([]byte, n)
398430
obj.Bread(f, p)
399431
return string(p)
400432
}
401433

402434
func rddata(f *obj.Biobuf) []byte {
403-
n := rdint(f)
435+
n := rdint64(f)
404436
p := make([]byte, n)
405437
obj.Bread(f, p)
406438
return p
@@ -409,9 +441,9 @@ func rddata(f *obj.Biobuf) []byte {
409441
var symbuf []byte
410442

411443
func rdsym(ctxt *Link, f *obj.Biobuf, pkg string) *LSym {
412-
n := int(rdint(f))
444+
n := rdint(f)
413445
if n == 0 {
414-
rdint(f)
446+
rdint64(f)
415447
return nil
416448
}
417449

@@ -420,7 +452,7 @@ func rdsym(ctxt *Link, f *obj.Biobuf, pkg string) *LSym {
420452
}
421453
obj.Bread(f, symbuf[:n])
422454
p := string(symbuf[:n])
423-
v := int(rdint(f))
455+
v := rdint(f)
424456
if v != 0 {
425457
v = ctxt.Version
426458
}

0 commit comments

Comments
 (0)