diff options
Diffstat (limited to 'pkg/osutil')
| -rw-r--r-- | pkg/osutil/osutil_unix.go | 38 | ||||
| -rw-r--r-- | pkg/osutil/sharedmem_file.go | 42 | ||||
| -rw-r--r-- | pkg/osutil/sharedmem_memfd.go | 30 |
3 files changed, 84 insertions, 26 deletions
diff --git a/pkg/osutil/osutil_unix.go b/pkg/osutil/osutil_unix.go index 0ab5dfd05..33cb09e40 100644 --- a/pkg/osutil/osutil_unix.go +++ b/pkg/osutil/osutil_unix.go @@ -96,33 +96,28 @@ func LongPipe() (io.ReadCloser, io.WriteCloser, error) { return r, w, err } +// ProcessExitStatus returns process exit status. +// This is here only because of fuchsia that does not implement WaitStatus. +func ProcessExitStatus(ps *os.ProcessState) int { + return ps.Sys().(syscall.WaitStatus).ExitStatus() +} + // CreateMemMappedFile creates a temp file with the requested size and maps it into memory. func CreateMemMappedFile(size int) (f *os.File, mem []byte, err error) { - f, err = ioutil.TempFile("./", "syzkaller-shm") + f, err = CreateSharedMemFile(size) if err != nil { - err = fmt.Errorf("failed to create temp file: %v", err) return } if err = f.Truncate(int64(size)); err != nil { - err = fmt.Errorf("failed to truncate shm file: %v", err) - f.Close() - os.Remove(f.Name()) - return - } - f.Close() - fname := f.Name() - f, err = os.OpenFile(f.Name(), os.O_RDWR, DefaultFilePerm) - if err != nil { - err = fmt.Errorf("failed to open shm file: %v", err) - os.Remove(fname) + err = fmt.Errorf("failed to truncate shared mem file: %v", err) + CloseSharedMemFile(f) return } + mem, err = syscall.Mmap(int(f.Fd()), 0, size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED) if err != nil { err = fmt.Errorf("failed to mmap shm file: %v", err) - f.Close() - os.Remove(f.Name()) - return + CloseSharedMemFile(f) } return } @@ -130,22 +125,13 @@ func CreateMemMappedFile(size int) (f *os.File, mem []byte, err error) { // CloseMemMappedFile destroys memory mapping created by CreateMemMappedFile. func CloseMemMappedFile(f *os.File, mem []byte) error { err1 := syscall.Munmap(mem) - err2 := f.Close() - err3 := os.Remove(f.Name()) + err2 := CloseSharedMemFile(f) switch { case err1 != nil: return err1 case err2 != nil: return err2 - case err3 != nil: - return err3 default: return nil } } - -// ProcessExitStatus returns process exit status. -// This is here only because of fuchsia that does not implement WaitStatus. -func ProcessExitStatus(ps *os.ProcessState) int { - return ps.Sys().(syscall.WaitStatus).ExitStatus() -} diff --git a/pkg/osutil/sharedmem_file.go b/pkg/osutil/sharedmem_file.go new file mode 100644 index 000000000..1e969cdba --- /dev/null +++ b/pkg/osutil/sharedmem_file.go @@ -0,0 +1,42 @@ +// Copyright 2021 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +//go:build freebsd || netbsd || openbsd || darwin +// +build freebsd netbsd openbsd darwin + +package osutil + +import ( + "fmt" + "io/ioutil" + "os" +) + +func CreateSharedMemFile(size int) (f *os.File, err error) { + f, err = ioutil.TempFile("./", "syzkaller-shm") + if err != nil { + err = fmt.Errorf("failed to create temp file: %v", err) + return + } + f.Close() + fname := f.Name() + f, err = os.OpenFile(f.Name(), os.O_RDWR, DefaultFilePerm) + if err != nil { + err = fmt.Errorf("failed to open shm file: %v", err) + os.Remove(fname) + } + return +} + +func CloseSharedMemFile(f *os.File) error { + err1 := f.Close() + err2 := os.Remove(f.Name()) + switch { + case err1 != nil: + return err1 + case err2 != nil: + return err2 + default: + return nil + } +} diff --git a/pkg/osutil/sharedmem_memfd.go b/pkg/osutil/sharedmem_memfd.go new file mode 100644 index 000000000..bdcea486f --- /dev/null +++ b/pkg/osutil/sharedmem_memfd.go @@ -0,0 +1,30 @@ +// Copyright 2021 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +//go:build linux +// +build linux + +package osutil + +import ( + "fmt" + "os" + + "golang.org/x/sys/unix" +) + +// In the case of Linux, we can just use the memfd_create syscall. +func CreateSharedMemFile(size int) (f *os.File, err error) { + // The name is actually irrelevant and can even be the same for all such files. + fd, err := unix.MemfdCreate("syz-shared-mem", 0) + if err != nil { + err = fmt.Errorf("failed to do memfd_create: %v", err) + return + } + f = os.NewFile(uintptr(fd), fmt.Sprintf("/proc/self/fd/%d", fd)) + return +} + +func CloseSharedMemFile(f *os.File) error { + return f.Close() +} |
