net/netstat: add some paranoia around syscall

Probably most of this doesn't matter.
pull/939/head
Josh Bleecher Snyder 2020-11-17 13:28:20 -08:00
parent d9e2edb5ae
commit 6ce1f7f817
1 changed files with 14 additions and 7 deletions

View File

@ -9,6 +9,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/bits" "math/bits"
"runtime"
"syscall" "syscall"
"unsafe" "unsafe"
@ -62,13 +63,13 @@ func get() (*Table, error) {
} }
func (t *Table) addEntries(fam int) error { func (t *Table) addEntries(fam int) error {
var size uint32 size := new(uint32)
var addr unsafe.Pointer var addr unsafe.Pointer
var buf []byte var buf []byte
for { for {
err, _, _ := getTCPTable.Call( err, _, _ := getTCPTable.Call(
uintptr(addr), uintptr(addr),
uintptr(unsafe.Pointer(&size)), uintptr(unsafe.Pointer(size)),
1, // sorted 1, // sorted
uintptr(fam), uintptr(fam),
tcpTableOwnerPidAll, tcpTableOwnerPidAll,
@ -79,19 +80,23 @@ func (t *Table) addEntries(fam int) error {
} }
if err == uintptr(syscall.ERROR_INSUFFICIENT_BUFFER) { if err == uintptr(syscall.ERROR_INSUFFICIENT_BUFFER) {
const maxSize = 10 << 20 const maxSize = 10 << 20
if size > maxSize || size < 4 { if *size > maxSize || *size < 4 {
return fmt.Errorf("unreasonable kernel-reported size %d", size) return fmt.Errorf("unreasonable kernel-reported size %d", *size)
} }
buf = make([]byte, size) buf = make([]byte, *size)
addr = unsafe.Pointer(&buf[0]) addr = unsafe.Pointer(&buf[0])
continue continue
} }
runtime.KeepAlive(size)
runtime.KeepAlive(addr)
return syscall.Errno(err) return syscall.Errno(err)
} }
if len(buf) < int(size) { if len(buf) < int(*size) {
runtime.KeepAlive(size)
runtime.KeepAlive(addr)
return errors.New("unexpected size growth from system call") return errors.New("unexpected size growth from system call")
} }
buf = buf[:size] buf = buf[:*size]
numEntries := *(*uint32)(unsafe.Pointer(&buf[0])) numEntries := *(*uint32)(unsafe.Pointer(&buf[0]))
buf = buf[4:] buf = buf[4:]
@ -128,6 +133,8 @@ func (t *Table) addEntries(fam int) error {
} }
buf = buf[recSize:] buf = buf[recSize:]
} }
runtime.KeepAlive(addr)
runtime.KeepAlive(size)
return nil return nil
} }