[tor-commits] [sandboxed-tor-browser/master] Handle bubblewrap crashing/exiting mid-setup.

yawning at torproject.org yawning at torproject.org
Mon Nov 28 02:26:16 UTC 2016


commit 7bb33aba93ad767c13be9776bb0e90eeb771db4f
Author: Yawning Angel <yawning at schwanenlied.me>
Date:   Mon Nov 28 02:03:34 2016 +0000

    Handle bubblewrap crashing/exiting mid-setup.
---
 .../internal/sandbox/hugbox.go                     | 103 ++++++++++++++-------
 1 file changed, 70 insertions(+), 33 deletions(-)

diff --git a/src/cmd/sandboxed-tor-browser/internal/sandbox/hugbox.go b/src/cmd/sandboxed-tor-browser/internal/sandbox/hugbox.go
index 8ecafa1..6f7528e 100644
--- a/src/cmd/sandboxed-tor-browser/internal/sandbox/hugbox.go
+++ b/src/cmd/sandboxed-tor-browser/internal/sandbox/hugbox.go
@@ -28,6 +28,7 @@ import (
 	"strconv"
 	"strings"
 	"syscall"
+	"time"
 
 	"cmd/sandboxed-tor-browser/internal/data"
 	. "cmd/sandboxed-tor-browser/internal/utils"
@@ -283,47 +284,83 @@ func (h *hugbox) run() (*exec.Cmd, error) {
 	// Fork/exec.
 	cmd.Start()
 
-	// Flush the pending writes.
-	for i, wrFd := range pendingWriteFds {
-		d := pendingWrites[i]
-		if err := writeBuffer(wrFd, d); err != nil {
-			cmd.Process.Kill()
-			return nil, err
+	// Do the rest of the setup in a go routine, and monitor completion and
+	// a watchdog timer.
+	doneCh := make(chan error)
+	bwrapPid := cmd.Process.Pid
+	hz := time.NewTicker(1 * time.Second)
+	defer hz.Stop()
+
+	go func() {
+		// Flush the pending writes.
+		for i, wrFd := range pendingWriteFds {
+			d := pendingWrites[i]
+			if err := writeBuffer(wrFd, d); err != nil {
+				doneCh <- err
+				return
+			}
+			cmd.ExtraFiles = cmd.ExtraFiles[1:]
 		}
-		cmd.ExtraFiles = cmd.ExtraFiles[1:]
-	}
 
-	// Write the seccomp rules.
-	if h.seccompFn != nil {
-		// This should be the one and only remaining extra file.
-		if len(cmd.ExtraFiles) != 2 {
-			panic("sandbox: unexpected extra files when writing seccomp rules")
-		} else if seccompWrFd == nil {
-			panic("sandbox: missing fd when writing seccomp rules")
+		// Write the seccomp rules.
+		if h.seccompFn != nil {
+			// This should be the one and only remaining extra file.
+			if len(cmd.ExtraFiles) != 2 {
+				panic("sandbox: unexpected extra files when writing seccomp rules")
+			} else if seccompWrFd == nil {
+				panic("sandbox: missing fd when writing seccomp rules")
+			}
+			if err := h.seccompFn(seccompWrFd); err != nil {
+				doneCh <- err
+				return
+			}
+			cmd.ExtraFiles = cmd.ExtraFiles[1:]
+		} else if seccompWrFd != nil {
+			panic("sandbox: seccomp fd exists when there are no rules to be written")
 		}
-		if err := h.seccompFn(seccompWrFd); err != nil {
-			cmd.Process.Kill()
-			return nil, err
+
+		// Read back the child pid.
+		decoder := json.NewDecoder(infoRdFd)
+		info := &bwrapInfo{}
+		if err := decoder.Decode(info); err != nil {
+			doneCh <- err
+			return
 		}
-		cmd.ExtraFiles = cmd.ExtraFiles[1:]
-	} else if seccompWrFd != nil {
-		panic("sandbox: seccomp fd exists when there are no rules to be written")
-	}
 
-	// Read back the child pid.
-	decoder := json.NewDecoder(infoRdFd)
-	info := &bwrapInfo{}
-	if err := decoder.Decode(info); err != nil {
-		return nil, err
-	}
+		Debugf("sandbox: bwrap pid is: %v", cmd.Process.Pid)
+		Debugf("sandbox: child pid is: %v", info.Pid)
 
-	Debugf("sandbox: bwrap pid is: %v", cmd.Process.Pid)
-	Debugf("sandbox: child pid is: %v", info.Pid)
+		// This is more useful to us, since it's fork of bubblewrap that will
+		// execvp.
+		cmd.Process.Pid = info.Pid
+
+		doneCh <- nil
+	}()
 
-	// This is more useful to us.
-	cmd.Process.Pid = info.Pid
+	err := fmt.Errorf("sandbox: timeout waiting for bubblewrap to start")
+timeoutLoop:
+	for nTicks := 0; nTicks < 10; { // 10 second timeout, probably excessive.
+		select {
+		case err = <-doneCh:
+			if err == nil {
+				return cmd, nil
+			}
+			break timeoutLoop
+		case <-hz.C:
+			var wstatus syscall.WaitStatus
+			_, err = syscall.Wait4(bwrapPid, &wstatus, syscall.WNOHANG, nil)
+			if err != nil {
+				break timeoutLoop
+			} else if wstatus.Exited() {
+				err = fmt.Errorf("sandbox: bubblewrap exited unexpectedly")
+				break timeoutLoop
+			}
+			nTicks++
+		}
+	}
 
-	return cmd, nil
+	cmd.Process.Kill()
+	return nil, err
 }
 
 type bwrapInfo struct {





More information about the tor-commits mailing list