From 381ccbf2f8752e9369efc68aacae65f769378ba3 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 8 Feb 2019 16:18:19 +0100 Subject: pkg/ipc: generate better temp name for executor Just appending the pid number can produce conflicting names if the name itself ends with digits (standard temp file naming convention). So append ".PID". Also remove beginning from too long names instead of ending. Temp files in tests has unique numbers at the end, we need to preserve them to avoid file name conflicts. --- pkg/ipc/ipc.go | 16 ++++++++-------- pkg/ipc/ipc_test.go | 3 ++- pkg/osutil/osutil_linux.go | 30 +++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go index ca740219e..b2d4c9d63 100644 --- a/pkg/ipc/ipc.go +++ b/pkg/ipc/ipc.go @@ -190,14 +190,15 @@ func MakeEnv(config *Config, pid int) (*Env, error) { env.bin[0] = osutil.Abs(env.bin[0]) // we are going to chdir // Append pid to binary name. // E.g. if binary is 'syz-executor' and pid=15, - // we create a link from 'syz-executor15' to 'syz-executor' and use 'syz-executor15' as binary. + // we create a link from 'syz-executor.15' to 'syz-executor' and use 'syz-executor.15' as binary. // This allows to easily identify program that lead to a crash in the log. - // Log contains pid in "executing program 15" and crashes usually contain "Comm: syz-executor15". + // Log contains pid in "executing program 15" and crashes usually contain "Comm: syz-executor.15". base := filepath.Base(env.bin[0]) - pidStr := fmt.Sprint(pid) - if len(base)+len(pidStr) >= 16 { - // TASK_COMM_LEN is currently set to 16 - base = base[:15-len(pidStr)] + pidStr := fmt.Sprintf(".%v", pid) + const maxLen = 16 // TASK_COMM_LEN is currently set to 16 + if len(base)+len(pidStr) >= maxLen { + // Remove beginning of file name, in tests temp files have unique numbers at the end. + base = base[len(base)+len(pidStr)-maxLen+1:] } binCopy := filepath.Join(filepath.Dir(env.bin[0]), base+pidStr) if err := os.Link(env.bin[0], binCopy); err == nil { @@ -514,8 +515,7 @@ type callReply struct { // signal/cover/comps follow } -func makeCommand(pid int, bin []string, config *Config, inFile, outFile *os.File, outmem []byte) ( - *command, error) { +func makeCommand(pid int, bin []string, config *Config, inFile, outFile *os.File, outmem []byte) (*command, error) { dir, err := ioutil.TempDir("./", "syzkaller-testdir") if err != nil { return nil, fmt.Errorf("failed to create temp dir: %v", err) diff --git a/pkg/ipc/ipc_test.go b/pkg/ipc/ipc_test.go index 8d0ca7ff5..42d066d08 100644 --- a/pkg/ipc/ipc_test.go +++ b/pkg/ipc/ipc_test.go @@ -127,8 +127,9 @@ func TestParallel(t *testing.T) { const P = 10 errs := make(chan error, P) for p := 0; p < P; p++ { + p := p go func() { - env, err := MakeEnv(cfg, 0) + env, err := MakeEnv(cfg, p) if err != nil { errs <- fmt.Errorf("failed to create env: %v", err) return diff --git a/pkg/osutil/osutil_linux.go b/pkg/osutil/osutil_linux.go index f4b30b195..1ec37d45f 100644 --- a/pkg/osutil/osutil_linux.go +++ b/pkg/osutil/osutil_linux.go @@ -11,6 +11,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strconv" "strings" "sync" @@ -30,7 +31,34 @@ func RemoveAll(dir string) error { fn := []byte(name + "\x00") syscall.Syscall(syscall.SYS_UMOUNT2, uintptr(unsafe.Pointer(&fn[0])), syscall.MNT_FORCE, 0) } - return os.RemoveAll(dir) + if err := os.RemoveAll(dir); err != nil { + removeImmutable(dir) + return os.RemoveAll(dir) + } + return nil +} + +func removeImmutable(fname string) error { + // Reset FS_XFLAG_IMMUTABLE/FS_XFLAG_APPEND. + fd, err := syscall.Open(fname, syscall.O_RDONLY, 0) + if err != nil { + return err + } + defer syscall.Close(fd) + flags := 0 + var cmd uint64 // FS_IOC_SETFLAGS + switch runtime.GOARCH { + case "386", "arm": + cmd = 1074030082 + case "amd64", "arm64": + cmd = 1074292226 + case "ppc64le": + cmd = 2148034050 + default: + panic("unknown arch") + } + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(&flags))) + return errno } func Sandbox(cmd *exec.Cmd, user, net bool) error { -- cgit mrf-deployment