aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/symbolizer
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/symbolizer
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/symbolizer')
-rw-r--r--pkg/symbolizer/nm.go28
-rw-r--r--pkg/symbolizer/nm_test.go2
2 files changed, 23 insertions, 7 deletions
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)
}