From 1ee782d53c445be1996975e1c7fd2b7bb063d4b7 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Wed, 3 Apr 2019 17:35:33 +0200 Subject: host: add kallsyms parsing tests Start with a few simple tests that can be extended when needed. --- pkg/host/host_linux.go | 42 +++++++++++++++++++-------------- pkg/host/host_test.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 18 deletions(-) (limited to 'pkg/host') diff --git a/pkg/host/host_linux.go b/pkg/host/host_linux.go index ca98d927b..ae8d7af85 100644 --- a/pkg/host/host_linux.go +++ b/pkg/host/host_linux.go @@ -67,23 +67,7 @@ func isSupported(c *prog.Syscall, target *prog.Target, sandbox string) (bool, st if len(kallsyms) == 0 { return } - var re *regexp.Regexp - switch target.Arch { - case "386", "amd64": - re = regexp.MustCompile(` T (__ia32_|__x64_)?sys_([^\n]+)\n`) - case "arm64": - re = regexp.MustCompile(` T (__arm64_)?sys_([^\n]+)\n`) - case "ppc64le": - re = regexp.MustCompile(` T ()?sys_([^\n]+)\n`) - default: - panic("unsupported arch for kallsyms parsing") - } - matches := re.FindAllSubmatch(kallsyms, -1) - for _, m := range matches { - name := string(m[2]) - log.Logf(2, "found in kallsyms: %v", name) - kallsymsSyscallSet[name] = true - } + kallsymsSyscallSet = parseKallsyms(kallsyms, target.Arch) }) if !testFallback && len(kallsymsSyscallSet) != 0 { r, v := isSupportedKallsyms(c) @@ -92,6 +76,28 @@ func isSupported(c *prog.Syscall, target *prog.Target, sandbox string) (bool, st return isSupportedTrial(c) } +func parseKallsyms(kallsyms []byte, arch string) map[string]bool { + set := make(map[string]bool) + var re *regexp.Regexp + switch arch { + case "386", "amd64": + re = regexp.MustCompile(` T (__ia32_|__x64_)?sys_([^\n]+)\n`) + case "arm64": + re = regexp.MustCompile(` T (__arm64_)?sys_([^\n]+)\n`) + case "ppc64le": + re = regexp.MustCompile(` T ()?sys_([^\n]+)\n`) + default: + panic("unsupported arch for kallsyms parsing") + } + matches := re.FindAllSubmatch(kallsyms, -1) + for _, m := range matches { + name := string(m[2]) + log.Logf(2, "found in kallsyms: %v", name) + set[name] = true + } + return set +} + func isSupportedKallsyms(c *prog.Syscall) (bool, string) { name := c.CallName if newname := kallsymsRenameMap[name]; newname != "" { @@ -144,7 +150,7 @@ func init() { // Where umount is renamed to oldumount is unclear. var ( kallsymsOnce sync.Once - kallsymsSyscallSet = make(map[string]bool) + kallsymsSyscallSet map[string]bool kallsymsRenameMap = map[string]string{ "umount": "oldumount", "umount2": "umount", diff --git a/pkg/host/host_test.go b/pkg/host/host_test.go index c8190dac5..43e063eaf 100644 --- a/pkg/host/host_test.go +++ b/pkg/host/host_test.go @@ -46,6 +46,70 @@ func TestDetectSupportedSyscalls(t *testing.T) { } } +func TestKallsymsParse(t *testing.T) { + tests := []struct { + Arch string + Kallsyms []byte + Syscalls []string + }{ + { + "amd64", + []byte(` +ffffffff817cdcc0 T __sys_bind +ffffffff817cdda0 T __x64_sys_bind +ffffffff817cddc0 T __ia32_sys_bind +ffffffff817cdde0 T __sys_listen +ffffffff817cde80 T __x64_sys_listen +ffffffff817cde90 T __ia32_sys_listen +ffffffff817cdea0 T __sys_accept4 +ffffffff817ce080 T __x64_sys_accept4 +ffffffff817ce0a0 T __ia32_sys_accept4 + `), + []string{"bind", "listen", "accept4"}, + }, + { + "arm64", + []byte(` +ffff000010a3ddf8 T __sys_bind +ffff000010a3def8 T __arm64_sys_bind +ffff000010a3df20 T __sys_listen +ffff000010a3dfd8 T __arm64_sys_listen +ffff000010a3e000 T __sys_accept4 +ffff000010a3e1f0 T __arm64_sys_accept4 + `), + []string{"bind", "listen", "accept4"}, + }, + { + "ppc64le", + []byte(` +c0000000011ec810 T __sys_bind +c0000000011eca10 T sys_bind +c0000000011eca10 T __se_sys_bind +c0000000011eca70 T __sys_listen +c0000000011ecc10 T sys_listen +c0000000011ecc10 T __se_sys_listen +c0000000011ecc70 T __sys_accept4 +c0000000011ed050 T sys_accept4 +c0000000011ed050 T __se_sys_accept4 + `), + []string{"bind", "listen", "accept4"}, + }, + } + + for _, test := range tests { + syscallSet := parseKallsyms(test.Kallsyms, test.Arch) + if len(syscallSet) != len(test.Syscalls) { + t.Fatalf("wrong number of parse syscalls, expected: %v, got: %v", + len(test.Syscalls), len(syscallSet)) + } + for _, syscall := range test.Syscalls { + if _, ok := syscallSet[syscall]; !ok { + t.Fatalf("syscall %v not found in parsed syscall list", syscall) + } + } + } +} + func TestCheck(t *testing.T) { t.Parallel() target, err := prog.GetTarget(runtime.GOOS, runtime.GOARCH) -- cgit mrf-deployment