aboutsummaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/macho/file.go57
1 files changed, 36 insertions, 21 deletions
diff --git a/src/debug/macho/file.go b/src/debug/macho/file.go
index e6b170a7cd..e35b4df508 100644
--- a/src/debug/macho/file.go
+++ b/src/debug/macho/file.go
@@ -253,9 +253,13 @@ func NewFile(r io.ReaderAt) (*File, error) {
if _, err := r.ReadAt(dat, offset); err != nil {
return nil, err
}
- f.Loads = make([]Load, f.Ncmd)
+ c := saferio.SliceCap([]Load{}, uint64(f.Ncmd))
+ if c < 0 {
+ return nil, &FormatError{offset, "too many load commands", nil}
+ }
+ f.Loads = make([]Load, 0, c)
bo := f.ByteOrder
- for i := range f.Loads {
+ for i := uint32(0); i < f.Ncmd; i++ {
// Each load command begins with uint32 command and length.
if len(dat) < 8 {
return nil, &FormatError{offset, "command block too small", nil}
@@ -270,7 +274,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
var s *Segment
switch cmd {
default:
- f.Loads[i] = LoadBytes(cmddat)
+ f.Loads = append(f.Loads, LoadBytes(cmddat))
case LoadCmdRpath:
var hdr RpathCmd
@@ -284,7 +288,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
}
l.Path = cstring(cmddat[hdr.Path:])
l.LoadBytes = LoadBytes(cmddat)
- f.Loads[i] = l
+ f.Loads = append(f.Loads, l)
case LoadCmdDylib:
var hdr DylibCmd
@@ -301,7 +305,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
l.CurrentVersion = hdr.CurrentVersion
l.CompatVersion = hdr.CompatVersion
l.LoadBytes = LoadBytes(cmddat)
- f.Loads[i] = l
+ f.Loads = append(f.Loads, l)
case LoadCmdSymtab:
var hdr SymtabCmd
@@ -319,15 +323,15 @@ func NewFile(r io.ReaderAt) (*File, error) {
} else {
symsz = 12
}
- symdat := make([]byte, int(hdr.Nsyms)*symsz)
- if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil {
+ symdat, err := saferio.ReadDataAt(r, uint64(hdr.Nsyms)*uint64(symsz), int64(hdr.Symoff))
+ if err != nil {
return nil, err
}
st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset)
if err != nil {
return nil, err
}
- f.Loads[i] = st
+ f.Loads = append(f.Loads, st)
f.Symtab = st
case LoadCmdDysymtab:
@@ -357,7 +361,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
st.LoadBytes = LoadBytes(cmddat)
st.DysymtabCmd = hdr
st.IndirectSyms = x
- f.Loads[i] = st
+ f.Loads = append(f.Loads, st)
f.Dysymtab = st
case LoadCmdSegment:
@@ -379,7 +383,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
s.Prot = seg32.Prot
s.Nsect = seg32.Nsect
s.Flag = seg32.Flag
- f.Loads[i] = s
+ f.Loads = append(f.Loads, s)
for i := 0; i < int(s.Nsect); i++ {
var sh32 Section32
if err := binary.Read(b, bo, &sh32); err != nil {
@@ -419,7 +423,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
s.Prot = seg64.Prot
s.Nsect = seg64.Nsect
s.Flag = seg64.Flag
- f.Loads[i] = s
+ f.Loads = append(f.Loads, s)
for i := 0; i < int(s.Nsect); i++ {
var sh64 Section64
if err := binary.Read(b, bo, &sh64); err != nil {
@@ -441,6 +445,12 @@ func NewFile(r io.ReaderAt) (*File, error) {
}
}
if s != nil {
+ if int64(s.Offset) < 0 {
+ return nil, &FormatError{offset, "invalid section offset", s.Offset}
+ }
+ if int64(s.Filesz) < 0 {
+ return nil, &FormatError{offset, "invalid section file size", s.Filesz}
+ }
s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz))
s.ReaderAt = s.sr
}
@@ -450,9 +460,13 @@ func NewFile(r io.ReaderAt) (*File, error) {
func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) {
bo := f.ByteOrder
- symtab := make([]Symbol, hdr.Nsyms)
+ c := saferio.SliceCap([]Symbol{}, uint64(hdr.Nsyms))
+ if c < 0 {
+ return nil, &FormatError{offset, "too many symbols", nil}
+ }
+ symtab := make([]Symbol, 0, c)
b := bytes.NewReader(symdat)
- for i := range symtab {
+ for i := 0; i < int(hdr.Nsyms); i++ {
var n Nlist64
if f.Magic == Magic64 {
if err := binary.Read(b, bo, &n); err != nil {
@@ -469,7 +483,6 @@ func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset
n.Desc = n32.Desc
n.Value = uint64(n32.Value)
}
- sym := &symtab[i]
if n.Name >= uint32(len(strtab)) {
return nil, &FormatError{offset, "invalid name in symbol table", n.Name}
}
@@ -478,11 +491,13 @@ func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset
if strings.Contains(name, ".") && name[0] == '_' {
name = name[1:]
}
- sym.Name = name
- sym.Type = n.Type
- sym.Sect = n.Sect
- sym.Desc = n.Desc
- sym.Value = n.Value
+ symtab = append(symtab, Symbol{
+ Name: name,
+ Type: n.Type,
+ Sect: n.Sect,
+ Desc: n.Desc,
+ Value: n.Value,
+ })
}
st := new(Symtab)
st.LoadBytes = LoadBytes(cmddat)
@@ -501,8 +516,8 @@ func (f *File) pushSection(sh *Section, r io.ReaderAt) error {
sh.ReaderAt = sh.sr
if sh.Nreloc > 0 {
- reldat := make([]byte, int(sh.Nreloc)*8)
- if _, err := r.ReadAt(reldat, int64(sh.Reloff)); err != nil {
+ reldat, err := saferio.ReadDataAt(r, uint64(sh.Nreloc)*8, int64(sh.Reloff))
+ if err != nil {
return err
}
b := bytes.NewReader(reldat)