diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-04-25 13:51:51 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-05-02 16:24:59 +0000 |
| commit | 22ee48a2879809608f79cc23c914859fa2335d59 (patch) | |
| tree | aa2b496eb81823999a8b48be011575ee7c650fff /pkg/vminfo/vminfo_test.go | |
| parent | 3c7bb2247f61c5218d4cd58a558dc2496fba53a4 (diff) | |
pkg/vminfo: check enabled syscalls on the host
Move the syscall checking logic to the host.
Diffing sets of disabled syscalls before/after this change
in different configurations (none/setuid sandboxes, amd64/386 arches,
large/small kernel configs) shows only some improvements/bug fixes.
1. socket$inet[6]_icmp are now enabled.
Previously they were disabled due to net.ipv4.ping_group_range sysctl
in the init namespace which prevented creation of ping sockets.
In the new net namespace the sysctl gets default value which allows creation.
2. get_thread_area and set_thread_area are now disabled on amd64.
They are available only in 32-bit mode, but they are present in /proc/kallsyms,
so we enabled them always.
3. socket$bt_{bnep, cmtp, hidp, rfcomm} are now disabled.
They cannot be created in non init net namespace.
bt_sock_create() checks init_net and returns EAFNOSUPPORT immediately.
This is a bug in descriptions we need to fix.
Now we see it due to more precise checks.
4. fstat64/fstatat64/lstat64/stat64 are now enabled in 32-bit mode.
They are not present in /proc/kallsyms as syscalls, so we have not enabled them.
But they are available in 32-bit mode.
5. 78 openat variants + 10 socket variants + mount are now disabled
with setuid sandbox. They are not permitted w/o root permissions,
but we ignored that. This additionally leads to 700 transitively
disabled syscalls.
In all cases checking in the actual executor context/sandbox
looks very positive, esp. for more restrictive sandboxes.
Android sandbox should benefit as well.
The additional benefit is full testability of the new code.
The change includes only a basic test that covers all checks,
and ensures the code does not crash/hang, all generated programs
parse successfully, etc. But it's possible to unit-test
every condition now.
The new version also parallelizes checking across VMs,
checking on a slow emulated qemu drops from 210 seconds
to 140 seconds.
Diffstat (limited to 'pkg/vminfo/vminfo_test.go')
| -rw-r--r-- | pkg/vminfo/vminfo_test.go | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/pkg/vminfo/vminfo_test.go b/pkg/vminfo/vminfo_test.go index e4dc1bfb8..9ffb0dd31 100644 --- a/pkg/vminfo/vminfo_test.go +++ b/pkg/vminfo/vminfo_test.go @@ -9,11 +9,14 @@ import ( "testing" "github.com/google/syzkaller/pkg/host" + "github.com/google/syzkaller/pkg/ipc" "github.com/google/syzkaller/pkg/mgrconfig" + "github.com/google/syzkaller/prog" + "github.com/google/syzkaller/sys/targets" ) func TestHostMachineInfo(t *testing.T) { - checker, files := hostChecker() + checker, files := hostChecker(t) dups := make(map[string]bool) for _, file := range files { if file.Name[0] != '/' || file.Name[len(file.Name)-1] == '/' || strings.Contains(file.Name, "\\") { @@ -38,15 +41,32 @@ func TestHostMachineInfo(t *testing.T) { } } -func hostChecker() (*Checker, []host.FileInfo) { +func hostChecker(t *testing.T) (*Checker, []host.FileInfo) { + cfg := testConfig(t, runtime.GOOS, runtime.GOARCH) + checker := New(cfg) + files := host.ReadFiles(checker.RequiredFiles()) + return checker, files +} + +func testConfig(t *testing.T, OS, arch string) *mgrconfig.Config { + target, err := prog.GetTarget(OS, arch) + if err != nil { + t.Fatal(err) + } cfg := &mgrconfig.Config{ + Sandbox: ipc.FlagsToSandbox(0), Derived: mgrconfig.Derived{ - TargetOS: runtime.GOOS, - TargetArch: runtime.GOARCH, - TargetVMArch: runtime.GOARCH, + TargetOS: OS, + TargetArch: arch, + TargetVMArch: arch, + Target: target, + SysTarget: targets.Get(OS, arch), }, } - checker := New(cfg) - files := host.ReadFiles(checker.RequiredFiles()) - return checker, files + for id := range target.Syscalls { + if !target.Syscalls[id].Attrs.Disabled { + cfg.Syscalls = append(cfg.Syscalls, id) + } + } + return cfg } |
