[98156] trunk/base

jmr at macports.org jmr at macports.org
Wed Sep 26 09:16:41 PDT 2012


Revision: 98156
          http://trac.macports.org//changeset/98156
Author:   jmr at macports.org
Date:     2012-09-26 09:16:41 -0700 (Wed, 26 Sep 2012)
Log Message:
-----------
add rudimentary sandboxing support for commands run via system proc

Modified Paths:
--------------
    trunk/base/configure
    trunk/base/configure.ac
    trunk/base/src/pextlib1.0/system.c
    trunk/base/src/port1.0/Makefile
    trunk/base/src/port1.0/port.tcl
    trunk/base/src/port1.0/port_autoconf.tcl.in

Added Paths:
-----------
    trunk/base/src/port1.0/portsandbox.tcl

Modified: trunk/base/configure
===================================================================
--- trunk/base/configure	2012-09-26 16:10:59 UTC (rev 98155)
+++ trunk/base/configure	2012-09-26 16:16:41 UTC (rev 98156)
@@ -710,6 +710,7 @@
 SWIG
 SVN
 SED
+SANDBOX_EXEC
 RSYNC
 RMDIR
 PAX
@@ -5544,6 +5545,46 @@
 fi
 
 
+# Extract the first word of "sandbox-exec", so it can be a program name with args.
+set dummy sandbox-exec; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_SANDBOX_EXEC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $SANDBOX_EXEC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_SANDBOX_EXEC="$SANDBOX_EXEC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_SANDBOX_EXEC="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+SANDBOX_EXEC=$ac_cv_path_SANDBOX_EXEC
+if test -n "$SANDBOX_EXEC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SANDBOX_EXEC" >&5
+$as_echo "$SANDBOX_EXEC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
 # Extract the first word of "sed", so it can be a program name with args.
 set dummy sed; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5

Modified: trunk/base/configure.ac
===================================================================
--- trunk/base/configure.ac	2012-09-26 16:10:59 UTC (rev 98155)
+++ trunk/base/configure.ac	2012-09-26 16:16:41 UTC (rev 98156)
@@ -133,6 +133,7 @@
 AC_PATH_PROG(PAX, [pax], [])
 AC_PATH_PROG(RMDIR, [rmdir], [])
 AC_PATH_PROG(RSYNC, [rsync], [])
+AC_PATH_PROG(SANDBOX_EXEC, [sandbox-exec], [], [/usr/bin])
 AC_PATH_PROG(SED, [sed])
 AC_PATH_PROG(SVN, [svn], [])
 AC_PATH_PROG(SWIG, [swig], [], [$PATH:/usr/local/bin])

Modified: trunk/base/src/pextlib1.0/system.c
===================================================================
--- trunk/base/src/pextlib1.0/system.c	2012-09-26 16:10:59 UTC (rev 98155)
+++ trunk/base/src/pextlib1.0/system.c	2012-09-26 16:16:41 UTC (rev 98156)
@@ -77,14 +77,42 @@
     char *line;
 };
 
+static int check_sandboxing(Tcl_Interp *interp, char **sandbox_exec_path, char **profilestr)
+{
+    Tcl_Obj *tcl_result;
+    int supported;
+    int len;
+
+    tcl_result = Tcl_GetVar2Ex(interp, "portsandbox_supported", NULL, TCL_GLOBAL_ONLY);
+    if (!tcl_result || Tcl_GetBooleanFromObj(interp, tcl_result, &supported) != TCL_OK || !supported) {
+        return 0;
+    }
+
+    tcl_result = Tcl_GetVar2Ex(interp, "portutil::autoconf::sandbox_exec_path", NULL, TCL_GLOBAL_ONLY);
+    if (!tcl_result || !(*sandbox_exec_path = Tcl_GetString(tcl_result))) {
+        return 0;
+    }
+
+    tcl_result = Tcl_GetVar2Ex(interp, "portsandbox_profile", NULL, TCL_GLOBAL_ONLY);
+    if (!tcl_result || !(*profilestr = Tcl_GetStringFromObj(tcl_result, &len)) 
+        || len == 0) {
+        return 0;
+    }
+
+    return 1;
+}
+
 /* usage: system ?-notty? ?-nice value? ?-W path? command */
 int SystemCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
 {
     char *buf;
     struct linebuf circbuf[CBUFSIZ];
     size_t linelen;
-    char *args[4];
+    char *args[7];
     char *cmdstring;
+    int sandbox = 0;
+    char *sandbox_exec_path;
+    char *profilestr;
     FILE *pdes;
     int fdset[2], nullfd;
     int fline, pos, ret;
@@ -128,6 +156,11 @@
         }
     }
 
+#if 0
+    /* check if and how we should use sandbox-exec */
+    sandbox = check_sandboxing(interp, &sandbox_exec_path, &profilestr);
+#endif
+
     /*
      * Fork a child to run the command, in a popen() like fashion -
      * popen() itself is not used because stderr is also desired.
@@ -178,11 +211,22 @@
         }
 
         /* XXX ugly string constants */
-        args[0] = "sh";
-        args[1] = "-c";
-        args[2] = cmdstring;
-        args[3] = NULL;
-        execve("/bin/sh", args, environ);
+        if (sandbox) {
+            args[0] = "sandbox-exec";
+            args[1] = "-p";
+            args[2] = profilestr;
+            args[3] = "sh";
+            args[4] = "-c";
+            args[5] = cmdstring;
+            args[6] = NULL;
+            execve(sandbox_exec_path, args, environ);
+        } else {
+            args[0] = "sh";
+            args[1] = "-c";
+            args[2] = cmdstring;
+            args[3] = NULL;
+            execve("/bin/sh", args, environ);
+        }
         _exit(1);
         break;
     default: /* parent */

Modified: trunk/base/src/port1.0/Makefile
===================================================================
--- trunk/base/src/port1.0/Makefile	2012-09-26 16:10:59 UTC (rev 98155)
+++ trunk/base/src/port1.0/Makefile	2012-09-26 16:16:41 UTC (rev 98156)
@@ -6,7 +6,8 @@
 	portlint.tcl portclean.tcl porttest.tcl portactivate.tcl \
 	portdeactivate.tcl portsubmit.tcl port_autoconf.tcl portstartupitem.tcl \
 	porttrace.tcl portlivecheck.tcl portdistcheck.tcl portmirror.tcl \
-	portload.tcl portunload.tcl portdistfiles.tcl fetch_common.tcl
+	portload.tcl portunload.tcl portdistfiles.tcl fetch_common.tcl \
+	portsandbox.tcl
 
 include ../../Mk/macports.subdir.mk
 include ../../Mk/macports.autoconf.mk

Modified: trunk/base/src/port1.0/port.tcl
===================================================================
--- trunk/base/src/port1.0/port.tcl	2012-09-26 16:10:59 UTC (rev 98155)
+++ trunk/base/src/port1.0/port.tcl	2012-09-26 16:16:41 UTC (rev 98156)
@@ -58,3 +58,4 @@
 package require portunload 1.0
 
 package require portdistfiles 1.0
+package require portsandbox 1.0

Modified: trunk/base/src/port1.0/port_autoconf.tcl.in
===================================================================
--- trunk/base/src/port1.0/port_autoconf.tcl.in	2012-09-26 16:10:59 UTC (rev 98155)
+++ trunk/base/src/port1.0/port_autoconf.tcl.in	2012-09-26 16:16:41 UTC (rev 98156)
@@ -65,6 +65,7 @@
 	variable xcode_select_path "@XCODE_SELECT@"
 	variable xcodebuild_path "@XCODEBUILD@"
 	variable xcrun_path "@XCRUN@"
+	variable sandbox_exec_path "@SANDBOX_EXEC@"
 	variable sed_command "@SED@"
 	variable sed_ext_flag "@SED_EXT@"
 	variable tar_command "@TAR_CMD@"

Added: trunk/base/src/port1.0/portsandbox.tcl
===================================================================
--- trunk/base/src/port1.0/portsandbox.tcl	                        (rev 0)
+++ trunk/base/src/port1.0/portsandbox.tcl	2012-09-26 16:16:41 UTC (rev 98156)
@@ -0,0 +1,71 @@
+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
+# $Id$
+#
+# Copyright (c) 2012 The MacPorts Project
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of The MacPorts Project nor the names of its
+#    contributors may be used to endorse or promote products derived from
+#    this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package provide portsandbox 1.0
+
+namespace eval portsandbox {
+}
+
+options portsandbox_supported portsandbox_profile
+default portsandbox_supported {[file executable $portutil::autoconf::sandbox_exec_path]}
+default portsandbox_profile {[portsandbox::get_default_profile]}
+
+# produce a suitable profile to pass to sandbox-exec
+# command line usage would be:
+# sandbox-exec -p '(version 1) (allow default) (deny file* (subpath "/usr/local") (subpath "/Library/Frameworks"))' some-command
+proc portsandbox::get_default_profile {} {
+    global os.major prefix frameworks_dir
+    set prefix_conflict [expr {$prefix == "/usr/local" || [string match $prefix "/usr/local/*"]}]
+    set frameworks_conflict [expr {$frameworks_dir == "/Library/Frameworks" || [string match $frameworks_dir "/Library/Frameworks/*"]}]
+    if {$prefix_conflict && $frameworks_conflict} {
+        return ""
+    }
+    set profile "(version 1) (allow default) (deny "
+    if {${os.major} > 9} {
+        append profile "file* "
+        if {!$prefix_conflict} {
+            append profile {(subpath "/usr/local")}
+        }
+        if {!$frameworks_conflict} {
+            append profile { (subpath "/Library/Frameworks")}
+        }
+    } else {
+        append profile "file-read* file-write* (regex "
+        if {!$prefix_conflict} {
+            append profile {#"^/usr/local/"}
+        }
+        if {!$frameworks_conflict} {
+            append profile { #"^/Library/Frameworks/"}
+        }
+        append profile ")"
+    }
+    append profile ")"
+    return $profile
+}


Property changes on: trunk/base/src/port1.0/portsandbox.tcl
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20120926/dacb069b/attachment-0001.html>


More information about the macports-changes mailing list