aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-01-22 12:17:20 +0100
committerDmitry Vyukov <dvyukov@google.com>2020-01-22 12:19:53 +0100
commit02754a8f9af246f440492295487282e55dc09cc0 (patch)
tree728b59573a119421b2a5e2b89f965edc9ff6f93a /pkg
parent8eda0b957e5b39c0c525e74f51d6b39ab8c5b1ac (diff)
tools/syz-check: check netlink policy descriptions
Overall idea of netlink checking. Currnetly we check netlink policies for common detectable mistakes. First, we detect what looks like a netlink policy in our descriptions (these are structs/unions only with nlattr/nlnext/nlnetw fields). Then we find corresponding symbols (offset/size) in vmlinux using nm. Then we read elf headers and locate where these symbols are in the rodata section. Then read in the symbol data, which is an array of nla_policy structs. These structs allow to easily figure out type/size of attributes. Finally we compare our descriptions with the kernel policy description. Update #590
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cover/report.go2
-rw-r--r--pkg/report/linux.go2
-rw-r--r--pkg/report/netbsd.go2
-rw-r--r--pkg/report/openbsd.go2
-rw-r--r--pkg/symbolizer/nm.go28
-rw-r--r--pkg/symbolizer/nm_test.go2
6 files changed, 27 insertions, 11 deletions
diff --git a/pkg/cover/report.go b/pkg/cover/report.go
index b92c5e982..d66d730b3 100644
--- a/pkg/cover/report.go
+++ b/pkg/cover/report.go
@@ -313,7 +313,7 @@ func (rg *ReportGenerator) findSymbol(pc uint64) uint64 {
}
func readSymbols(obj string) ([]symbol, error) {
- raw, err := symbolizer.ReadSymbols(obj)
+ raw, err := symbolizer.ReadTextSymbols(obj)
if err != nil {
return nil, fmt.Errorf("failed to run nm on %v: %v", obj, err)
}
diff --git a/pkg/report/linux.go b/pkg/report/linux.go
index ac9a78ee5..968bc1692 100644
--- a/pkg/report/linux.go
+++ b/pkg/report/linux.go
@@ -38,7 +38,7 @@ func ctorLinux(cfg *config) (Reporter, []string, error) {
if cfg.kernelObj != "" {
vmlinux = filepath.Join(cfg.kernelObj, cfg.target.KernelObject)
var err error
- symbols, err = symbolizer.ReadSymbols(vmlinux)
+ symbols, err = symbolizer.ReadTextSymbols(vmlinux)
if err != nil {
return nil, nil, err
}
diff --git a/pkg/report/netbsd.go b/pkg/report/netbsd.go
index 036e9dc9c..69287ed58 100644
--- a/pkg/report/netbsd.go
+++ b/pkg/report/netbsd.go
@@ -37,7 +37,7 @@ func ctorNetbsd(cfg *config) (Reporter, []string, error) {
if cfg.kernelObj != "" {
kernelObject = filepath.Join(cfg.kernelObj, cfg.target.KernelObject)
var err error
- symbols, err = symbolizer.ReadSymbols(kernelObject)
+ symbols, err = symbolizer.ReadTextSymbols(kernelObject)
if err != nil {
return nil, nil, err
}
diff --git a/pkg/report/openbsd.go b/pkg/report/openbsd.go
index 9cf1a593b..99e49c81c 100644
--- a/pkg/report/openbsd.go
+++ b/pkg/report/openbsd.go
@@ -36,7 +36,7 @@ func ctorOpenbsd(cfg *config) (Reporter, []string, error) {
if cfg.kernelObj != "" {
kernelObject = filepath.Join(cfg.kernelObj, cfg.target.KernelObject)
var err error
- symbols, err = symbolizer.ReadSymbols(kernelObject)
+ symbols, err = symbolizer.ReadTextSymbols(kernelObject)
if err != nil {
return nil, nil, err
}
diff --git a/pkg/symbolizer/nm.go b/pkg/symbolizer/nm.go
index caa246629..09baf8119 100644
--- a/pkg/symbolizer/nm.go
+++ b/pkg/symbolizer/nm.go
@@ -16,8 +16,21 @@ type Symbol struct {
Size int
}
-// ReadSymbols returns list of text symbols in the binary bin.
-func ReadSymbols(bin string) (map[string][]Symbol, error) {
+// ReadTextSymbols returns list of text symbols in the binary bin.
+func ReadTextSymbols(bin string) (map[string][]Symbol, error) {
+ return read(bin, "t", "T")
+}
+
+// ReadRodataSymbols returns list of rodata symbols in the binary bin.
+func ReadRodataSymbols(bin string) (map[string][]Symbol, error) {
+ return read(bin, "r", "R")
+}
+
+func read(bin string, types ...string) (map[string][]Symbol, error) {
+ if len(types) != 2 || len(types[0]) != 1 || len(types[1]) != 1 {
+ // We assume these things below.
+ panic("bad types")
+ }
cmd := osutil.Command("nm", "-Ptx", bin)
stdout, err := cmd.StdoutPipe()
if err != nil {
@@ -30,11 +43,14 @@ func ReadSymbols(bin string) (map[string][]Symbol, error) {
defer cmd.Wait()
symbols := make(map[string][]Symbol)
s := bufio.NewScanner(stdout)
- text := [][]byte{[]byte(" t "), []byte(" T ")}
+ var tt [][]byte
+ for _, typ := range types {
+ tt = append(tt, []byte(" "+typ+" "))
+ }
for s.Scan() {
// A line looks as: "snb_uncore_msr_enable_box t ffffffff8104db90 0000000000000059"
ln := s.Bytes()
- if !bytes.Contains(ln, text[0]) && !bytes.Contains(ln, text[1]) {
+ if !bytes.Contains(ln, tt[0]) && !bytes.Contains(ln, tt[1]) {
continue
}
@@ -42,11 +58,11 @@ func ReadSymbols(bin string) (map[string][]Symbol, error) {
if sp1 == -1 {
continue
}
- if !bytes.HasPrefix(ln[sp1:], text[0]) && !bytes.HasPrefix(ln[sp1:], text[1]) {
+ if !bytes.HasPrefix(ln[sp1:], tt[0]) && !bytes.HasPrefix(ln[sp1:], tt[1]) {
continue
}
- sp2 := sp1 + len(text[0])
+ sp2 := sp1 + len(tt[0])
sp3 := bytes.IndexByte(ln[sp2:], ' ')
if sp3 == -1 {
continue
diff --git a/pkg/symbolizer/nm_test.go b/pkg/symbolizer/nm_test.go
index 44a02f3cc..6061608ec 100644
--- a/pkg/symbolizer/nm_test.go
+++ b/pkg/symbolizer/nm_test.go
@@ -8,7 +8,7 @@ import (
)
func TestSymbols(t *testing.T) {
- symbols, err := ReadSymbols("testdata/nm.test.out")
+ symbols, err := ReadTextSymbols("testdata/nm.test.out")
if err != nil {
t.Fatalf("failed to read symbols: %v", err)
}