Skip to content

Commit

Permalink
cmd/link/internal/ld: stricter object file decoding
Browse files Browse the repository at this point in the history
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 golang#11617.

Change-Id: Ia7b577270f8438ca7479262702371e26277f1ea7
Reviewed-on: https://go-review.googlesource.com/12050
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
mdempsky committed Jul 10, 2015
1 parent 6a90b1d commit 1082e23
Showing 1 changed file with 59 additions and 27 deletions.
86 changes: 59 additions & 27 deletions src/cmd/link/internal/ld/objfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,22 +164,22 @@ func readsym(ctxt *Link, f *obj.Biobuf, pkg string, pn string) {
if obj.Bgetc(f) != 0xfe {
log.Fatalf("readsym out of sync")
}
t := int(rdint(f))
t := rdint(f)
name := expandpkg(rdstring(f), pkg)
v := int(rdint(f))
v := rdint(f)
if v != 0 && v != 1 {
log.Fatalf("invalid symbol version %d", v)
}
flags := int(rdint(f))
flags := rdint(f)
dupok := flags & 1
local := false
if flags&2 != 0 {
local = true
}
size := int(rdint(f))
size := rdint(f)
typ := rdsym(ctxt, f, pkg)
data := rddata(f)
nreloc := int(rdint(f))
nreloc := rdint(f)

if v != 0 {
v = ctxt.Version
Expand Down Expand Up @@ -241,11 +241,11 @@ overwrite:
var r *Reloc
for i := 0; i < nreloc; i++ {
r = &s.R[i]
r.Off = int32(rdint(f))
r.Siz = uint8(rdint(f))
r.Type = int32(rdint(f))
r.Add = rdint(f)
rdint(f) // Xadd, ignored
r.Off = rdint32(f)
r.Siz = rduint8(f)
r.Type = rdint32(f)
r.Add = rdint64(f)
rdint64(f) // Xadd, ignored
r.Sym = rdsym(ctxt, f, pkg)
rdsym(ctxt, f, pkg) // Xsym, ignored
}
Expand All @@ -260,19 +260,19 @@ overwrite:
}

if s.Type == obj.STEXT {
s.Args = int32(rdint(f))
s.Locals = int32(rdint(f))
s.Nosplit = uint8(rdint(f))
v := int(rdint(f))
s.Args = rdint32(f)
s.Locals = rdint32(f)
s.Nosplit = rduint8(f)
v := rdint(f)
s.Leaf = uint8(v & 1)
s.Cfunc = uint8(v & 2)
n := int(rdint(f))
n := rdint(f)
var a *Auto
for i := 0; i < n; i++ {
a = new(Auto)
a.Asym = rdsym(ctxt, f, pkg)
a.Aoffset = int32(rdint(f))
a.Name = int16(rdint(f))
a.Aoffset = rdint32(f)
a.Name = rdint16(f)
a.Gotype = rdsym(ctxt, f, pkg)
a.Link = s.Autom
s.Autom = a
Expand All @@ -283,23 +283,23 @@ overwrite:
pc.Pcsp.P = rddata(f)
pc.Pcfile.P = rddata(f)
pc.Pcline.P = rddata(f)
n = int(rdint(f))
n = rdint(f)
pc.Pcdata = make([]Pcdata, n)
pc.Npcdata = n
for i := 0; i < n; i++ {
pc.Pcdata[i].P = rddata(f)
}
n = int(rdint(f))
n = rdint(f)
pc.Funcdata = make([]*LSym, n)
pc.Funcdataoff = make([]int64, n)
pc.Nfuncdata = n
for i := 0; i < n; i++ {
pc.Funcdata[i] = rdsym(ctxt, f, pkg)
}
for i := 0; i < n; i++ {
pc.Funcdataoff[i] = rdint(f)
pc.Funcdataoff[i] = rdint64(f)
}
n = int(rdint(f))
n = rdint(f)
pc.File = make([]*LSym, n)
pc.Nfile = n
for i := 0; i < n; i++ {
Expand Down Expand Up @@ -374,7 +374,7 @@ overwrite:
}
}

func rdint(f *obj.Biobuf) int64 {
func rdint64(f *obj.Biobuf) int64 {
var c int

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

func rdint(f *obj.Biobuf) int {
n := rdint64(f)
if int64(int(n)) != n {
log.Panicf("%v out of range for int", n)
}
return int(n)
}

func rdint32(f *obj.Biobuf) int32 {
n := rdint64(f)
if int64(int32(n)) != n {
log.Panicf("%v out of range for int32", n)
}
return int32(n)
}

func rdint16(f *obj.Biobuf) int16 {
n := rdint64(f)
if int64(int16(n)) != n {
log.Panicf("%v out of range for int16", n)
}
return int16(n)
}

func rduint8(f *obj.Biobuf) uint8 {
n := rdint64(f)
if int64(uint8(n)) != n {
log.Panicf("%v out of range for uint8", n)
}
return uint8(n)
}

func rdstring(f *obj.Biobuf) string {
n := rdint(f)
n := rdint64(f)
p := make([]byte, n)
obj.Bread(f, p)
return string(p)
}

func rddata(f *obj.Biobuf) []byte {
n := rdint(f)
n := rdint64(f)
p := make([]byte, n)
obj.Bread(f, p)
return p
Expand All @@ -409,9 +441,9 @@ func rddata(f *obj.Biobuf) []byte {
var symbuf []byte

func rdsym(ctxt *Link, f *obj.Biobuf, pkg string) *LSym {
n := int(rdint(f))
n := rdint(f)
if n == 0 {
rdint(f)
rdint64(f)
return nil
}

Expand All @@ -420,7 +452,7 @@ func rdsym(ctxt *Link, f *obj.Biobuf, pkg string) *LSym {
}
obj.Bread(f, symbuf[:n])
p := string(symbuf[:n])
v := int(rdint(f))
v := rdint(f)
if v != 0 {
v = ctxt.Version
}
Expand Down

0 comments on commit 1082e23

Please sign in to comment.