[tor-commits] [sandboxed-tor-browser/master] This is the first pass at trying to constrain resource use by sandboxed

yawning at torproject.org yawning at torproject.org
Mon Dec 5 10:34:43 UTC 2016


commit 82fcc3247c878cff63bbf34fe0c397638a232bde
Author: Yawning Angel <yawning at schwanenlied.me>
Date:   Mon Dec 5 10:30:37 2016 +0000

    This is the first pass at trying to constrain resource use by sandboxed
    processes.
    
    I still need to decide what to do about `RLIMIT_AS`, `RLIMIT_DATA`,
    and `RLIMIT_FSIZE`.  I agree that setting them would be sensible, but
    it needs UI integration, which will take some thinking.
---
 src/cmd/gen-seccomp/seccomp_firefox.go             |   2 +-
 .../internal/sandbox/rlimit.go                     | 110 +++++++++++++++++++++
 src/cmd/sandboxed-tor-browser/internal/ui/ui.go    |   5 +
 3 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/src/cmd/gen-seccomp/seccomp_firefox.go b/src/cmd/gen-seccomp/seccomp_firefox.go
index 465d8fe..75a7dd3 100644
--- a/src/cmd/gen-seccomp/seccomp_firefox.go
+++ b/src/cmd/gen-seccomp/seccomp_firefox.go
@@ -117,7 +117,6 @@ func compileTorBrowserSeccompProfile(fd *os.File, is386 bool) error {
 		"brk",
 		"mincore",
 		"mmap",
-		"mlock",
 		"mprotect",
 		"mremap",
 		"munmap",
@@ -182,6 +181,7 @@ func compileTorBrowserSeccompProfile(fd *os.File, is386 bool) error {
 		// "vfork",
 		// "memfd_create", (PulseAudio?  Won't work in our container.)
 		// "personality",
+		// "mlock",
 	}
 	if is386 {
 		allowedNoArgs386 := []string{
diff --git a/src/cmd/sandboxed-tor-browser/internal/sandbox/rlimit.go b/src/cmd/sandboxed-tor-browser/internal/sandbox/rlimit.go
new file mode 100644
index 0000000..9ac9aed
--- /dev/null
+++ b/src/cmd/sandboxed-tor-browser/internal/sandbox/rlimit.go
@@ -0,0 +1,110 @@
+// rlimit.go - Resource limits.
+// Copyright (C) 2016  Yawning Angel.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package sandbox
+
+import "syscall"
+
+func lowerRlimit(resource int, newHard uint64) error {
+	var lim syscall.Rlimit
+	if err := syscall.Getrlimit(resource, &lim); err != nil {
+		return err
+	}
+
+	needsSet := false
+	if newHard < lim.Max {
+		lim.Max = newHard
+		needsSet = true
+	}
+	if newHard < lim.Cur {
+		lim.Cur = newHard
+		needsSet = true
+	}
+	if !needsSet {
+		return nil
+	}
+
+	return syscall.Setrlimit(resource, &lim)
+}
+
+// SetSensibleRlimits conservatively lowers the rlimits to values that will
+// happily support firefox, the updater, tor, and obfs4proxy.
+//
+// XXX; In the future, this should be applied to each process individually.
+// I still need to think about what I'll do for the things that are unset,
+// because it should be tied into the UI.
+func SetSensibleRlimits() error {
+	const (
+		limStack      = 512 * 1024 // 512 KiB
+		limRSS        = 0          // No effect as of 2.6.x...
+		limNproc      = 512
+		limNofile     = 1024 // Could maybe go as low as 512...
+		limMlock      = 0    // This might need to be increased later.
+		limLocks      = 32
+		limSigpending = 64
+		limMsgqueue   = 0 // Disallowed by seccomp.
+		limNice       = 0
+		limRtprio     = 0
+		limRttime     = 0
+
+		// The syscall package doesn't expose these.
+		RLIMIT_RSS        = 5
+		RLIMIT_NPROC      = 6
+		RLIMIT_MLOCK      = 8
+		RLIMIT_LOCKS      = 10
+		RLIMIT_SIGPENDING = 11
+		RLIMIT_MSGQUEUE   = 12
+		RLIMIT_NICE       = 13
+		RLIMIT_RTPRIO     = 14
+		RLIMIT_RTTIME     = 15
+	)
+
+	if err := lowerRlimit(syscall.RLIMIT_STACK, limStack); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_RSS, limRSS); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_NPROC, limNproc); err != nil {
+		return err
+	}
+	if err := lowerRlimit(syscall.RLIMIT_NOFILE, limNofile); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_MLOCK, limMlock); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_LOCKS, limLocks); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_SIGPENDING, limSigpending); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_MSGQUEUE, limMsgqueue); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_NICE, limNice); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_RTPRIO, limRtprio); err != nil {
+		return err
+	}
+	if err := lowerRlimit(RLIMIT_RTTIME, limRttime); err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/src/cmd/sandboxed-tor-browser/internal/ui/ui.go b/src/cmd/sandboxed-tor-browser/internal/ui/ui.go
index b2ca8ee..cd9a8c1 100644
--- a/src/cmd/sandboxed-tor-browser/internal/ui/ui.go
+++ b/src/cmd/sandboxed-tor-browser/internal/ui/ui.go
@@ -206,6 +206,11 @@ func (c *Common) Run() error {
 		log.SetOutput(w)
 	}
 
+	// Set sensible rlimits.
+	if err = sandbox.SetSensibleRlimits(); err != nil {
+		return err
+	}
+
 	// Acquire the lock file.
 	if c.lock, err = newLockFile(c); err != nil {
 		return err



More information about the tor-commits mailing list