commit 82fcc3247c878cff63bbf34fe0c397638a232bde
Author: Yawning Angel <yawn...@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

_______________________________________________
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to