diff options
| author | Damien Neil <dneil@google.com> | 2016-06-03 15:04:53 -0700 |
|---|---|---|
| committer | Damien Neil <dneil@google.com> | 2016-09-20 19:27:57 +0000 |
| commit | f5f7d6e32d5384a3638325ff8393bf94ec8d6971 (patch) | |
| tree | f03ae9f878d3fbcd85b419e238f19e5e512d38e5 /src/syscall/syscall_linux.go | |
| parent | ab5923572984651af05a47755109642bfc529cb5 (diff) | |
| download | go-f5f7d6e32d5384a3638325ff8393bf94ec8d6971.tar.xz | |
syscall: validate ParseDirent inputs
Don't panic, crash, or return references to uninitialized memory when
ParseDirent is passed invalid input.
Move common dirent parsing to syscall.go with minimal platform-specific
functions in syscall_$GOOS.go.
Fixes #15653
Change-Id: I5602475e02321fe381064488401c14b33bec6886
Reviewed-on: https://go-review.googlesource.com/23780
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/syscall/syscall_linux.go')
| -rw-r--r-- | src/syscall/syscall_linux.go | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go index 73a16f8959..d70e471ba5 100644 --- a/src/syscall/syscall_linux.go +++ b/src/syscall/syscall_linux.go @@ -757,38 +757,24 @@ func Reboot(cmd int) (err error) { return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") } -func clen(n []byte) int { - for i := 0; i < len(n); i++ { - if n[i] == 0 { - return i - } - } - return len(n) -} - func ReadDirent(fd int, buf []byte) (n int, err error) { return Getdents(fd, buf) } -func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { - origlen := len(buf) - count = 0 - for max != 0 && len(buf) > 0 { - dirent := (*Dirent)(unsafe.Pointer(&buf[0])) - buf = buf[dirent.Reclen:] - if dirent.Ino == 0 { // File absent in directory. - continue - } - bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) - var name = string(bytes[0:clen(bytes[:])]) - if name == "." || name == ".." { // Useless names - continue - } - max-- - count++ - names = append(names, name) +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + reclen, ok := direntReclen(buf) + if !ok { + return 0, false } - return origlen - len(buf), count, names + return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true } //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) |
