aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-01-11 17:28:34 +0100
committerDmitry Vyukov <dvyukov@google.com>2016-01-11 17:28:34 +0100
commit31d1087c3f39cc48bde5983ca43764a366cc0d2c (patch)
tree83c9e79c2f2e7a82305b3246db065a67c1a7c343
parent4f3c86c9504d001347f231d8ef0f3690b1d2434d (diff)
ipc: umount all mounts before removing temp dirs
This is needed if unshare(CLONE_NEWNS) is not implemented. Otherwise, os.RemoveAll fails.
-rw-r--r--fileutil/fileutil.go14
-rw-r--r--ipc/ipc.go3
2 files changed, 17 insertions, 0 deletions
diff --git a/fileutil/fileutil.go b/fileutil/fileutil.go
index a019a14ea..b84088354 100644
--- a/fileutil/fileutil.go
+++ b/fileutil/fileutil.go
@@ -12,6 +12,7 @@ import (
"strconv"
"sync"
"syscall"
+ "unsafe"
)
var copyMu sync.Mutex
@@ -103,3 +104,16 @@ func ProcessTempDir(where string) (string, int, error) {
}
return "", 0, fmt.Errorf("too many live instances")
}
+
+// UmountAll recurusively unmounts all mounts in dir.
+func UmountAll(dir string) {
+ files, _ := ioutil.ReadDir(dir)
+ for _, f := range files {
+ name := filepath.Join(dir, f.Name())
+ if f.IsDir() {
+ UmountAll(name)
+ }
+ fn := []byte(name + "\x00")
+ syscall.Syscall(syscall.SYS_UMOUNT2, uintptr(unsafe.Pointer(&fn[0])), syscall.MNT_FORCE, 0)
+ }
+}
diff --git a/ipc/ipc.go b/ipc/ipc.go
index 85904d2fa..95ac83b0b 100644
--- a/ipc/ipc.go
+++ b/ipc/ipc.go
@@ -16,6 +16,7 @@ import (
"syscall"
"time"
+ "github.com/google/syzkaller/fileutil"
"github.com/google/syzkaller/prog"
)
@@ -356,6 +357,7 @@ func (c *command) close() {
c.kill()
c.cmd.Wait()
}
+ fileutil.UmountAll(c.dir)
os.RemoveAll(c.dir)
if c.rp != nil {
c.rp.Close()
@@ -400,6 +402,7 @@ func (c *command) exec() (output, strace []byte, failed, hanged bool, err0 error
//!!! handle c.rp overflow
_, readErr := c.inrp.Read(tmp[:])
close(done)
+ fileutil.UmountAll(c.dir)
os.RemoveAll(c.dir)
if err := os.Mkdir(c.dir, 0777); err != nil {
<-hang