aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/host/host_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/host/host_linux.go')
-rw-r--r--pkg/host/host_linux.go38
1 files changed, 11 insertions, 27 deletions
diff --git a/pkg/host/host_linux.go b/pkg/host/host_linux.go
index 8214b35af..5c5db793b 100644
--- a/pkg/host/host_linux.go
+++ b/pkg/host/host_linux.go
@@ -469,7 +469,7 @@ func setupLeakChecking() error {
return nil
}
-func callbackLeakChecking() {
+func callbackLeakChecking(leakFrames [][]byte) {
start := time.Now()
fd, err := syscall.Open("/sys/kernel/debug/kmemleak", syscall.O_RDWR, 0)
if err != nil {
@@ -506,11 +506,15 @@ func callbackLeakChecking() {
if _, err := syscall.Write(fd, []byte("scan")); err != nil {
panic(err)
}
+ if _, err := syscall.Seek(fd, 0, 0); err != nil {
+ panic(err)
+ }
n, err := syscall.Read(fd, buf)
if err != nil {
panic(err)
}
nleaks := 0
+ nextLeak:
for buf = buf[:n]; len(buf) != 0; {
end := bytes.Index(buf[1:], []byte("unreferenced object"))
if end != -1 {
@@ -520,14 +524,18 @@ func callbackLeakChecking() {
}
report := buf[:end]
buf = buf[end:]
- if kmemleakIgnore(report) {
- continue
+ for _, frame := range leakFrames {
+ if bytes.Contains(report, frame) {
+ continue nextLeak
+ }
}
// BUG in output should be recognized by manager.
fmt.Printf("BUG: memory leak\n%s\n", report)
nleaks++
}
if nleaks != 0 {
+ // If we exit right away, dying executors will dump lots of garbage to console.
+ time.Sleep(time.Hour)
os.Exit(1)
}
}
@@ -536,30 +544,6 @@ func callbackLeakChecking() {
}
}
-func kmemleakIgnore(report []byte) bool {
- // kmemleak has a bunch of false positives (at least what looks like
- // false positives at first glance). So we are conservative with what we report.
- // First, we filter out any allocations that don't come from executor processes.
- // Second, we ignore a bunch of functions entirely.
- // Ideally, someone should debug/fix all these cases and remove ignores.
- if !bytes.Contains(report, []byte(`comm "syz-executor`)) {
- return true
- }
- for _, ignore := range []string{
- " copy_process",
- " do_execveat_common",
- " __ext4_",
- " get_empty_filp",
- " do_filp_open",
- " new_inode",
- } {
- if bytes.Contains(report, []byte(ignore)) {
- return true
- }
- }
- return false
-}
-
func checkSandboxNamespace() string {
if err := osutil.IsAccessible("/proc/self/ns/user"); err != nil {
return err.Error()