[policycoreutils/f15] Fix the handling of namespaces in seunshare/sandbox. Currently mounting of directories within sandbo

Daniel J Walsh dwalsh at fedoraproject.org
Tue Jan 3 16:12:53 UTC 2012


commit 72a4d21573ef39fb700785ad5f3b5f8f5234ad57
Author: Dan Walsh <dwalsh at redhat.com>
Date:   Tue Jan 3 11:12:49 2012 -0500

    Fix the handling of namespaces in seunshare/sandbox.
    Currently mounting of directories within sandbox is propogating to the
    parent namesspace.

 policycoreutils-sandbox.patch |  690 +++++++++++++++++++++++++++++++++++++----
 policycoreutils.spec          |    7 +-
 2 files changed, 633 insertions(+), 64 deletions(-)
---
diff --git a/policycoreutils-sandbox.patch b/policycoreutils-sandbox.patch
index 4fcc345..24d9fb7 100644
--- a/policycoreutils-sandbox.patch
+++ b/policycoreutils-sandbox.patch
@@ -1,6 +1,6 @@
 diff -up policycoreutils-2.0.86/restorecond/restorecond_user.conf.sandbox policycoreutils-2.0.86/restorecond/restorecond_user.conf
---- policycoreutils-2.0.86/restorecond/restorecond_user.conf.sandbox	2011-06-13 13:47:06.552590955 -0400
-+++ policycoreutils-2.0.86/restorecond/restorecond_user.conf	2011-06-13 13:47:27.757820459 -0400
+--- policycoreutils-2.0.86/restorecond/restorecond_user.conf.sandbox	2011-06-13 13:47:06.000000000 -0400
++++ policycoreutils-2.0.86/restorecond/restorecond_user.conf	2011-06-13 13:47:27.000000000 -0400
 @@ -4,4 +4,4 @@
  ~/local/*
  ~/.fonts/*
@@ -8,27 +8,39 @@ diff -up policycoreutils-2.0.86/restorecond/restorecond_user.conf.sandbox policy
 -
 +~/.config/*
 diff -up policycoreutils-2.0.86/sandbox/sandbox.8.sandbox policycoreutils-2.0.86/sandbox/sandbox.8
---- policycoreutils-2.0.86/sandbox/sandbox.8.sandbox	2011-07-07 14:42:18.298415909 -0400
-+++ policycoreutils-2.0.86/sandbox/sandbox.8	2011-07-07 14:42:30.567508958 -0400
+--- policycoreutils-2.0.86/sandbox/sandbox.8.sandbox	2011-07-07 14:42:18.000000000 -0400
++++ policycoreutils-2.0.86/sandbox/sandbox.8	2012-01-03 11:09:22.391519370 -0500
 @@ -3,11 +3,11 @@
  sandbox \- Run cmd under an SELinux sandbox
  .SH SYNOPSIS
  .B sandbox
 -[-l level ] [[-M | -X]  -H homedir -T tempdir ] [-I includefile ] [ -W windowmanager ] [ -w windowsize ] [[-i file ]...] [ -t type ] cmd
-+[-C] [-c] [-l level ] [[-M | -X]  -H homedir -T tempdir ] [-I includefile ] [ -W windowmanager ] [ -w windowsize ] [[-i file ]...] [ -t type ] cmd
++[-C] [-c] [ -d DPI ] [-l level ] [[-M | -X]  -H homedir -T tempdir ] [-I includefile ] [ -W windowmanager ] [ -w windowsize ] [[-i file ]...] [ -t type ] cmd
  
  .br
  .B sandbox
 -[-l level ] [[-M | -X]  -H homedir -T tempdir ] [-I includefile ] [ -W windowmanager ] [ -w windowsize ] [[-i file ]...] [ -t type ] -S
-+[-C] [-c] [-l level ] [[-M | -X]  -H homedir -T tempdir ] [-I includefile ] [ -W windowmanager ] [ -w windowsize ] [[-i file ]...] [ -t type ] -S
++[-C] [-c] [ -d DPI ] [-l level ] [[-M | -X]  -H homedir -T tempdir ] [-I includefile ] [ -W windowmanager ] [ -w windowsize ] [[-i file ]...] [ -t type ] -S
  .br
  .SH DESCRIPTION
  .PP
-@@ -60,8 +60,11 @@ Default to /usr/bin/matchbox-window-mana
+@@ -49,7 +49,7 @@ Use alternate tempory directory to mount
+ Run a full desktop session, Requires level, and home and tmpdir.
+ .TP
+ \fB\-w windowsize\fR
+-Specifies the windowsize when creating an X based Sandbox. The default windowsize is 1000x700. 
++Specifies the windowsize when creating an X based Sandbox. The default windowsize is 1000x700.
+ .TP
+ \fB\-W windowmanager\fR
+ Select alternative window manager to run within 
+@@ -60,8 +60,14 @@ Default to /usr/bin/matchbox-window-mana
  Create an X based Sandbox for gui apps, temporary files for
  $HOME and /tmp, secondary Xserver, defaults to sandbox_x_t
  .TP
 -\fB\-C\fR
++\fB\-d\fR
++Set the DPI value for the sanbox X Server. Defaults to the current X Sever DPI.
++.TP
 +\fB\-c\fR
  Use control groups to control this copy of sandbox.  Specify parameters in /etc/sysconfig/sandbox.  Max memory usage and cpu usage are to be specified in percent.  You can specify which CPUs to use by numbering them 0,1,2... etc.
 +.TP
@@ -37,9 +49,27 @@ diff -up policycoreutils-2.0.86/sandbox/sandbox.8.sandbox policycoreutils-2.0.86
  .PP
  .SH "SEE ALSO"
  .TP
+@@ -69,7 +75,7 @@ runcon(1), seunshare(8), selinux(8)
+ .PP
+ 
+ .SH AUTHOR
+-This manual page was written by 
++This manual page was written by
+ .I Dan Walsh <dwalsh at redhat.com>
+ and
+ .I Thomas Liu <tliu at fedoraproject.org>
 diff -up policycoreutils-2.0.86/sandbox/sandbox.sandbox policycoreutils-2.0.86/sandbox/sandbox
---- policycoreutils-2.0.86/sandbox/sandbox.sandbox	2011-06-13 13:44:44.678086035 -0400
-+++ policycoreutils-2.0.86/sandbox/sandbox	2011-07-07 14:42:50.587660702 -0400
+--- policycoreutils-2.0.86/sandbox/sandbox.sandbox	2011-06-13 13:44:44.000000000 -0400
++++ policycoreutils-2.0.86/sandbox/sandbox	2012-01-03 11:08:43.619495043 -0500
+@@ -25,7 +25,7 @@ import selinux
+ import signal
+ from tempfile import mkdtemp
+ import pwd
+-import commands 
++import commands
+ import setools
+ 
+ PROGNAME = "policycoreutils"
 @@ -88,9 +88,7 @@ def copyfile(file, srcdir, dest):
  
                except shutil.Error, elist:
@@ -51,31 +81,168 @@ diff -up policycoreutils-2.0.86/sandbox/sandbox.sandbox policycoreutils-2.0.86/s
                       
                SAVE_FILES[file] = (dest, os.path.getmtime(dest))
  
-@@ -311,17 +309,21 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+@@ -120,10 +118,30 @@ def reserve(level):
+     sock.bind("\0%s" % level)
+     fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+ 
++def get_range():
++       try:
++              level =selinux.getcon_raw()[1].split(":")[4]
++              lowc,highc = level.split(".")
++              low = int(lowc[1:])
++              high = int(highc[1:])+1
++              if high - low == 0:
++                     raise IndexError
++
++              return low,high
++       except IndexError:
++              raise ValueError(_("User account must be setup with an MCS Range"))
++
+ def gen_mcs():
+-       while True:
+-              i1 = random.randrange(0, 1024)
+-              i2 = random.randrange(0, 1024)
++       low, high = get_range()
++
++       level = None
++       ctr = 0
++       total = high-low
++       total = (total * (total - 1))/2
++       while ctr < total:
++              ctr += 1
++              i1 = random.randrange(low, high)
++              i2 = random.randrange(low, high)
+               if i1 == i2:
+                      continue
+               if i1 > i2:
+@@ -136,7 +154,10 @@ def gen_mcs():
+               except socket.error:
+                      continue
+               break
+-       return level
++       if level:
++              return level
++       raise ValueError(_("Failed to find any unused category sets.  Consider a larger MCS range for this user."))
++
+ 
+ def fullpath(cmd):
+        for i in [ "/", "./", "../" ]:
+@@ -170,7 +191,7 @@ class Sandbox:
+ 
+            if not os.path.exists(SEUNSHARE):
+                   raise ValueError(_("""
+-%s is required for the action you want to perform.  
++%s is required for the action you want to perform.
+ """) % SEUNSHARE)
+ 
+     def __mount_callback(self, option, opt, value, parser):
+@@ -181,12 +202,12 @@ class Sandbox:
+            setattr(parser.values, option.dest, True)
+            if not os.path.exists(SEUNSHARE):
+                   raise ValueError(_("""
+-%s is required for the action you want to perform.  
++%s is required for the action you want to perform.
+ """) % SEUNSHARE)
+ 
+            if not os.path.exists(SANDBOXSH):
+                   raise ValueError(_("""
+-%s is required for the action you want to perform.  
++%s is required for the action you want to perform.
+ """) % SANDBOXSH)
+ 
+     def __validdir(self, option, opt, value, parser):
+@@ -246,26 +267,25 @@ kill -TERM $WM_PID  2> /dev/null
+ 
+     def usage(self, message = ""):
+            error_exit("%s\n%s" % (self.__parser.usage, message))
+-           
++
+     def __parse_options(self):
+         from optparse import OptionParser
+         types = ""
+         try:
+                types = _("""
+-Policy defines the following types for use with the -t: 
++Policy defines the following types for use with the -t:
+ \t%s
+ """) % "\n\t".join(setools.seinfo(setools.ATTRIBUTE, "sandbox_type")[0]['types'])
+         except RuntimeError:
+                pass
+ 
+         usage = _("""
+-sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] command
++sandbox [-h] [-c] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] command
+ 
+-sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] -S
++sandbox [-h] [-c] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] -S
+ %s
+ """) % types
+ 
+-        
+         parser = OptionParser(version=self.VERSION, usage=usage)
+         parser.disable_interspersed_args()
+         parser.add_option("-i", "--include", 
+@@ -281,6 +301,10 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+                           action="callback", callback=self.__mount_callback, 
+                           help=_("mount new home and/or tmp directory"))
+ 
++        parser.add_option("-d", "--dpi",
++                          dest="dpi", action="store",
++                          help=_("dots per inch for X display"))
++
+         parser.add_option("-S", "--session", action="store_true",  dest="session", 
+                           default=False,  help=_("run complete desktop session within sandbox"))
+ 
+@@ -291,17 +315,17 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+         parser.add_option("-H", "--homedir", 
+                           action="callback", callback=self.__validdir,
+                           type="string",
+-                          dest="homedir",  
++                          dest="homedir",
+                           help=_("alternate home directory to use for mounting"))
+ 
+-        parser.add_option("-T", "--tmpdir", dest="tmpdir",  
++        parser.add_option("-T", "--tmpdir", dest="tmpdir",
+                           type="string",
+                           action="callback", callback=self.__validdir,
+                           help=_("alternate /tmp directory to use for mounting"))
+ 
+         parser.add_option("-w", "--windowsize", dest="windowsize",
+                           type="string", default=DEFAULT_WINDOWSIZE,
+-                          help="size of the sandbox window")		
++                          help="size of the sandbox window")
+ 
+         parser.add_option("-W", "--windowmanager", dest="wm",  
+                           type="string",
+@@ -311,9 +335,13 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
          parser.add_option("-l", "--level", dest="level", 
                            help=_("MCS/MLS level for the sandbox"))
  
 -        parser.add_option("-C", "--cgroups",
+-                         action="store_true", dest="usecgroup", default=False,
+-                         help="Use cgroups to limit this sandbox.")
 +        parser.add_option("-c", "--cgroups",
-                          action="store_true", dest="usecgroup", default=False,
-                          help="Use cgroups to limit this sandbox.")
- 
++                          action="store_true", dest="usecgroup", default=False,
++                          help=_("Use cgroups to limit this sandbox."))
++
 +        parser.add_option("-C", "--capabilities",
 +                         action="store_true", dest="usecaps", default=False,
 +                         help="Allow apps requiring capabilities to run within the sandbox.")
-+
-         self.__parser=parser
  
-         self.__options, cmds = parser.parse_args()
+         self.__parser=parser
  
-         if self.__options.X_ind:
-                self.setype = DEFAULT_X_TYPE
--
-+               self.dpi=commands.getoutput("xrdb -query | grep dpi  | /bin/cut -f 2")
-         if self.__options.setype:
-                self.setype = self.__options.setype
+@@ -366,8 +394,8 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
  
-@@ -392,8 +394,12 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+            con = selinux.getcon()[1].split(":")
+            self.__execcon = "%s:%s:%s:%s" % (con[0], con[1], self.setype, level)
+-           self.__filecon = "%s:%s:%s:%s" % (con[0], "object_r", 
+-                                             "%s_file_t" % self.setype[:-2], 
++           self.__filecon = "%s:%s:%s:%s" % (con[0], "object_r",
++                                             "%s_file_t" % self.setype[:-2],
+                                              level)
+     def __setup_dir(self):
+            if self.__options.level or self.__options.session:
+@@ -392,12 +420,20 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
      def __execute(self):
             try:
                    cmds = [ SEUNSHARE,  "-Z", self.__execcon ]
@@ -84,37 +251,46 @@ diff -up policycoreutils-2.0.86/sandbox/sandbox.sandbox policycoreutils-2.0.86/s
                           cmds.append('-c')
 +                  if self.__options.usecaps:
 +                         cmds.append('-C')
-+                  if not self.__options.level:
-+                         cmds.append('-k')
                    if self.__mount:
                           cmds +=  [ "-t", self.__tmpdir, "-h", self.__homedir ]
  
-@@ -405,7 +411,7 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+                          if self.__options.X_ind:
++                                if self.__options.dpi:
++                                       dpi = self.__options.dpi
++                                else:
++                                       import gtk
++                                       dpi = str(gtk.settings_get_default().props.gtk_xft_dpi/1024)
++
+                                 xmodmapfile = self.__homedir + "/.xmodmap"
+                                 xd = open(xmodmapfile,"w")
+                                 subprocess.Popen(["/usr/bin/xmodmap","-pke"],stdout=xd).wait()
+@@ -405,7 +441,7 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
  
                                  self.__setup_sandboxrc(self.__options.wm)
  
 -                                cmds += [ "--", SANDBOXSH, self.__options.windowsize ]
-+                                cmds += [ "--", SANDBOXSH, self.__options.windowsize, self.dpi ]
++                                cmds += [ "--", SANDBOXSH, self.__options.windowsize, dpi ]
                           else:
                                  cmds += [ "--" ] + self.__paths
                           return subprocess.Popen(cmds).wait()
 diff -up policycoreutils-2.0.86/sandbox/sandboxX.sh.sandbox policycoreutils-2.0.86/sandbox/sandboxX.sh
---- policycoreutils-2.0.86/sandbox/sandboxX.sh.sandbox	2011-06-13 13:44:44.684086096 -0400
-+++ policycoreutils-2.0.86/sandbox/sandboxX.sh	2011-07-07 14:41:50.536205201 -0400
+--- policycoreutils-2.0.86/sandbox/sandboxX.sh.sandbox	2011-06-13 13:44:44.000000000 -0400
++++ policycoreutils-2.0.86/sandbox/sandboxX.sh	2012-01-03 11:10:04.985546365 -0500
 @@ -1,10 +1,12 @@
- #!/bin/bash 
+-#!/bin/bash 
 -context=`id -Z | secon -t `
 -export TITLE="`grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8-80` ($context)"
 -[ $# -eq 1 ] && export SCREENSIZE="$1" || export SCREENSIZE="1000x700"
++#!/bin/bash
 +trap "" TERM
 +context=`id -Z | secon -t -l -P`
 +export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8-80`"
-+[ -z $1 ] && export SCREENSIZE="1000x700" || export SCREENSIZE="$1" 
-+[ -z $2 ] && export DPI="96" || export DPI="$2" 
++[ -z $1 ] && export SCREENSIZE="1000x700" || export SCREENSIZE="$1"
++[ -z $2 ] && export DPI="96" || export DPI="$2"
  trap "exit 0" HUP
  
 -(/usr/bin/Xephyr -nolisten tcp -title "$TITLE" -terminate -screen $SCREENSIZE -displayfd 5 5>&1 2>/dev/null) | while read D; do 
-+(/usr/bin/Xephyr -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -displayfd 5 5>&1 2>/dev/null) | while read D; do 
++(/usr/bin/Xephyr -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -displayfd 5 5>&1 2>/dev/null) | while read D; do
      export DISPLAY=:$D
      cat > ~/seremote << __EOF
  #!/bin/sh
@@ -128,17 +304,22 @@ diff -up policycoreutils-2.0.86/sandbox/sandboxX.sh.sandbox policycoreutils-2.0.
  done
  exit 0
 diff -up policycoreutils-2.0.86/sandbox/seunshare.8.sandbox policycoreutils-2.0.86/sandbox/seunshare.8
---- policycoreutils-2.0.86/sandbox/seunshare.8.sandbox	2011-07-07 14:41:16.065943281 -0400
-+++ policycoreutils-2.0.86/sandbox/seunshare.8	2011-07-07 14:41:26.300021079 -0400
-@@ -3,7 +3,7 @@
+--- policycoreutils-2.0.86/sandbox/seunshare.8.sandbox	2011-07-07 14:41:16.000000000 -0400
++++ policycoreutils-2.0.86/sandbox/seunshare.8	2012-01-03 11:10:36.498566587 -0500
+@@ -3,11 +3,11 @@
  seunshare \- Run cmd with alternate homedir, tmpdir and/or SELinux context
  .SH SYNOPSIS
  .B seunshare
 -[ -v ] [ -t tmpdir ] [ -h homedir ] [ -Z context ] -- executable [args]
-+[-v] [-c] [-C] [-k] [ -t tmpdir ] [ -h homedir ] [ -Z context ] -- executable [args]
++[ -v ] [ -c ] [ -C ] [ -k ] [ -t tmpdir ] [ -h homedir ] [ -Z context ] -- executable [args]
  .br
  .SH DESCRIPTION
  .PP
+-Run the 
++Run the
+ .I executable
+ within the specified context, using the alternate home directory and /tmp directory.  The seunshare command unshares from the default namespace, then mounts the specified homedir and tmpdir over the default homedir and /tmp. Finally it tells the kernel to execute the application under the specified SELinux context.
+ 
 @@ -18,9 +18,15 @@ Alternate homedir to be used by the appl
  \fB\-t\ tmpdir
  Use alternate tempory directory to mount on /tmp.  tmpdir must be owned by the user.
@@ -156,9 +337,41 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.8.sandbox policycoreutils-2.0.
  \fB\-Z\ context
  Use alternate SELinux context while runing the executable.
  .TP
+@@ -28,10 +34,10 @@ Use alternate SELinux context while runi
+ Verbose output
+ .SH "SEE ALSO"
+ .TP
+-runcon(1), sandbox(8), selinux(8)	
++runcon(1), sandbox(8), selinux(8)
+ .PP
+ .SH AUTHOR
+-This manual page was written by 
++This manual page was written by
+ .I Dan Walsh <dwalsh at redhat.com>
+ and
+ .I Thomas Liu <tliu at fedoraproject.org>
 diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.86/sandbox/seunshare.c
---- policycoreutils-2.0.86/sandbox/seunshare.c.sandbox	2011-06-13 13:44:44.687086129 -0400
-+++ policycoreutils-2.0.86/sandbox/seunshare.c	2011-07-07 14:41:08.038882237 -0400
+--- policycoreutils-2.0.86/sandbox/seunshare.c.sandbox	2011-06-13 13:44:44.000000000 -0400
++++ policycoreutils-2.0.86/sandbox/seunshare.c	2012-01-03 11:08:59.081504712 -0500
+@@ -5,8 +5,9 @@
+ 
+ #define _GNU_SOURCE
+ #include <signal.h>
+-#include <sys/types.h>
++#include <sys/fsuid.h>
+ #include <sys/stat.h>
++#include <sys/types.h>
+ #include <sys/wait.h>
+ #include <syslog.h>
+ #include <sys/mount.h>
+@@ -18,7 +19,6 @@
+ #include <stdio.h>
+ #include <regex.h>
+ #include <unistd.h>
+-#include <sys/fsuid.h>
+ #include <stdlib.h>
+ #include <cap-ng.h>
+ #include <getopt.h>		/* for getopt_long() form of getopt() */
 @@ -29,6 +29,7 @@
  
  #include <selinux/selinux.h>
@@ -167,12 +380,24 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  
  #ifdef USE_NLS
  #include <locale.h>		/* for setlocale() */
-@@ -53,20 +54,22 @@
+@@ -42,8 +43,8 @@
+ #define MS_REC 1<<14
+ #endif
+ 
+-#ifndef MS_PRIVATE
+-#define MS_PRIVATE 1<<18
++#ifndef MS_SLAVE
++#define MS_SLAVE 1<<19
+ #endif
+ 
+ #ifndef PACKAGE
+@@ -52,21 +53,22 @@
+ 
  #define BUF_SIZE 1024
  #define DEFAULT_PATH "/usr/bin:/bin"
- 
+-
 -#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -c ] -t tmpdir -h homedir [-Z context] -- executable [args]")
-+#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -c ] -C -t tmpdir -h homedir [-Z context] -- executable [args]")
++#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -C ] [ -c ] [ -k ] [ -t tmpdir ] [ -h homedir ] [ -Z CONTEXT ] -- executable [args] ")
  
  static int verbose = 0;
 +static int child = 0;
@@ -194,7 +419,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  		fprintf(stderr, _("Failed to drop all capabilities\n"));
  		return -1;
  	}
-@@ -86,6 +89,13 @@ static int drop_privs(uid_t uid)
+@@ -86,6 +88,13 @@ static int drop_privs(uid_t uid)
  }
  
  /**
@@ -208,39 +433,226 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
   * Take care of any signal setup.
   */
  static int set_signal_handles(void)
-@@ -101,7 +111,12 @@ static int set_signal_handles(void)
+@@ -101,11 +110,16 @@ static int set_signal_handles(void)
  	(void)sigprocmask(SIG_SETMASK, &empty, NULL);
  
  	/* Terminate on SIGHUP */
 -	if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
 +	if (signal(SIGHUP, SIG_DFL) == SIG_ERR) {
-+		perror("Unable to set SIGHUP handler");
+ 		perror("Unable to set SIGHUP handler");
+ 		return -1;
+ 	}
+ 
++	if (signal(SIGINT, handler) == SIG_ERR) {
++		perror("Unable to set SIGINT handler");
 +		return -1;
 +	}
 +
-+	if (signal(SIGINT, handler) == SIG_ERR) {
- 		perror("Unable to set SIGHUP handler");
+ 	return 0;
+ }
+ 
+@@ -192,7 +206,7 @@ static int verify_directory(const char *
+ 	struct stat sb;
+ 
+ 	if (st_out == NULL) st_out = &sb;
+-	
++
+ 	if (lstat(dir, st_out) == -1) {
+ 		fprintf(stderr, _("Failed to stat %s: %s\n"), dir, strerror(errno));
  		return -1;
+@@ -241,7 +255,7 @@ static int verify_shell(const char *shel
+  */
+ static int seunshare_mount(const char *src, const char *dst, struct stat *src_st)
+ {
+-	int flags = MS_REC;
++	int flags = 0;
+ 	int is_tmp = 0;
+ 
+ 	if (verbose)
+@@ -253,14 +267,6 @@ static int seunshare_mount(const char *s
  	}
-@@ -334,6 +349,7 @@ static int setup_cgroups()
+ 
+ 	/* mount directory */
+-	if (mount(dst, dst,  NULL, MS_BIND | flags, NULL) < 0) {
+-		fprintf(stderr, _("Failed to mount %s on %s: %s\n"), dst, dst, strerror(errno));
+-		return -1;
+-	}
+-	if (mount(dst, dst, NULL, MS_PRIVATE | flags, NULL) < 0) {
+-		fprintf(stderr, _("Failed to make %s private: %s\n"), dst, strerror(errno));
+-		return -1;
+-	}
+ 	if (mount(src, dst, NULL, MS_BIND | flags, NULL) < 0) {
+ 		fprintf(stderr, _("Failed to mount %s on %s: %s\n"), src, dst, strerror(errno));
+ 		return -1;
+@@ -274,14 +280,6 @@ static int seunshare_mount(const char *s
+ 		if (verbose)
+ 			printf(_("Mounting /tmp on /var/tmp\n"));
+ 
+-		if (mount("/var/tmp", "/var/tmp",  NULL, MS_BIND | flags, NULL) < 0) {
+-			fprintf(stderr, _("Failed to mount /var/tmp on /var/tmp: %s\n"), strerror(errno));
+-			return -1;
+-		}
+-		if (mount("/var/tmp", "/var/tmp", NULL, MS_PRIVATE | flags, NULL) < 0) {
+-			fprintf(stderr, _("Failed to make /var/tmp private: %s\n"), strerror(errno));
+-			return -1;
+-		}
+ 		if (mount("/tmp", "/var/tmp",  NULL, MS_BIND | flags, NULL) < 0) {
+ 			fprintf(stderr, _("Failed to mount /tmp on /var/tmp: %s\n"), strerror(errno));
+ 			return -1;
+@@ -308,12 +306,12 @@ static int sandbox_error(const char *str
+ static int match(const char *string, char *pattern)
+ {
+ 	int status;
+-	regex_t re; 
++	regex_t re;
+ 	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) {
+ 		return 0;
+ 	}
+ 	status = regexec(&re, string, (size_t)0, NULL, 0);
+-	regfree(&re);	
++	regfree(&re);
+ 	if (status != 0) {
+ 		return 0;
+ 	}
+@@ -334,8 +332,9 @@ static int setup_cgroups()
  	char buf[BUF_SIZE];
  	char *tok = NULL;
  	int rc = -1;
+-	const char* fname = "/etc/sysconfig/sandbox";	
+-	
 +	char *str = NULL;
- 	const char* fname = "/etc/sysconfig/sandbox";	
- 	
++	const char* fname = "/etc/sysconfig/sandbox";
++
  	if ((fp = fopen(fname, "rt")) == NULL) {
-@@ -346,7 +362,8 @@ static int setup_cgroups()
- 		
+ 		fprintf(stderr, "Error opening sandbox config file.");
+ 		return rc;
+@@ -343,12 +342,15 @@ static int setup_cgroups()
+ 	while(fgets(buf, BUF_SIZE, fp) != NULL) {
+ 		/* Skip comments */
+ 		if (buf[0] == '#') continue;
+-		
++
  		/* Copy the string, ignoring whitespace */
  		int len = strlen(buf);
 -		char *str = malloc((len + 1) * sizeof(char));
+-		
+-		int ind = 0;	
 +		free(str);
 +		str = malloc((len + 1) * sizeof(char));
- 		
- 		int ind = 0;	
++		if (!str)
++			goto err;
++
++		int ind = 0;
  		int i;
-@@ -487,6 +504,8 @@ static int setup_cgroups()
+ 		for (i = 0; i < len; i++) {
+ 			char cur = buf[i];
+@@ -358,7 +360,7 @@ static int setup_cgroups()
+ 			}
+ 		}
+ 		str[ind] = '\0';
+-		
++
+ 		tok = strtok(str, "=\n");
+ 		if (tok != NULL) {
+ 			if (!strcmp(tok, "CPUAFFINITY")) {
+@@ -382,7 +384,7 @@ static int setup_cgroups()
+ 					fprintf(stderr, "Error parsing config file.");
+ 					goto err;
+ 				}
+-				
++
+ 			} else if (!strcmp(tok, "CPUUSAGE")) {
+ 				tok = strtok(NULL, "=\n");
+ 				if (match(tok, "^[0-9]+\%")) {
+@@ -400,14 +402,14 @@ static int setup_cgroups()
+ 				continue;
+ 			}
+ 		}
+-		
++
+ 	}
+ 	if (mem == NULL) {
+ 		long phypz = sysconf(_SC_PHYS_PAGES);
+ 		long psize = sysconf(_SC_PAGE_SIZE);
+ 		memusage = phypz * psize * (float) memusage / 100.0;
+ 	}
+-	
++
+ 	cgroup_init();
+ 
+ 	int64_t current_runtime = 0;
+@@ -423,8 +425,8 @@ static int setup_cgroups()
+ 		cgroup_get_cgroup(curr);
+ 		cgroup_get_value_int64(cgroup_get_controller(curr, "cpu"), "cpu.rt_runtime_us", &current_runtime);
+ 		cgroup_get_value_int64(cgroup_get_controller(curr, "cpu"), "cpu.rt_period_us", &current_period);
+-	}   
+-	
++	}
++
+ 	ret  = cgroup_get_current_controller_path(getpid(), "memory", &curr_mem_path);
+ 	if (ret) {
+ 		sandbox_error("Error while trying to get current controller path.\n");
+@@ -432,33 +434,33 @@ static int setup_cgroups()
+ 		struct cgroup *curr = cgroup_new_cgroup(curr_mem_path);
+ 		cgroup_get_cgroup(curr);
+ 		cgroup_get_value_int64(cgroup_get_controller(curr, "memory"), "memory.limit_in_bytes", &current_mem);
+-	}   
+-	
++	}
++
+ 	if (((float) cpupercentage)  / 100.0> (float)current_runtime / (float) current_period) {
+ 		sandbox_error("CPU usage restricted!\n");
+ 		goto err;
+-	}   
+-	
+-	if (mem == NULL) {	
++	}
++
++	if (mem == NULL) {
+ 		if (memusage > current_mem) {
+ 			sandbox_error("Attempting to use more memory than allowed!");
+ 			goto err;
+ 		}
+ 	}
+-	
++
+ 	long nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+-	
+-	struct sched_param sp; 
++
++	struct sched_param sp;
+ 	sp.sched_priority = sched_get_priority_min(SCHED_FIFO);
+ 	sched_setscheduler(getpid(), SCHED_FIFO, &sp);
+ 	struct cgroup *sandbox_group = cgroup_new_cgroup(cgroupname);
+ 	cgroup_add_controller(sandbox_group, "memory");
+ 	cgroup_add_controller(sandbox_group, "cpu");
+-	
++
+ 	if (mem == NULL) {
+ 		if (memusage > 0) {
+ 			cgroup_set_value_uint64(cgroup_get_controller(sandbox_group, "memory"), "memory.limit_in_bytes", memusage);
+-		}	
++		}
+ 	} else {
+ 		cgroup_set_value_string(cgroup_get_controller(sandbox_group, "memory"), "memory.limit_in_bytes", mem);
+ 	}
+@@ -470,13 +472,13 @@ static int setup_cgroups()
+ 	if (cpus != NULL) {
+ 		cgroup_set_value_string(cgroup_get_controller(sandbox_group, "cpu"), "cgroup.procs",cpus);
+ 	}
+-	
++
+ 	uint64_t allocated_mem;
+ 	if (cgroup_get_value_uint64(cgroup_get_controller(sandbox_group, "memory"), "memory.limit_in_bytes", &allocated_mem) > current_mem) {
+ 		sandbox_error("Attempting to use more memory than allowed!\n");
+ 		goto err;
+ 	}
+-	
++
+ 	rc = cgroup_create_cgroup(sandbox_group, 1);
+ 	if (rc != 0) {
+ 		sandbox_error("Failed to create group.  Ensure that cgconfig service is running. \n");
+@@ -487,13 +489,15 @@ static int setup_cgroups()
  
  	rc = 0;
  err:
@@ -249,7 +661,57 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  	free(mem);
  	free(cgroupname);
  	free(cpus);
-@@ -734,12 +753,75 @@ good:
+ 	return rc;
+ }
+ 
+-/* 
++/*
+    If path is empy or ends with  "/." or "/.. return -1 else return 0;
+  */
+ static int bad_path(const char *path) {
+@@ -515,7 +519,7 @@ static int bad_path(const char *path) {
+ 	return 0;
+ }
+ 
+-static int rsynccmd(const char * src, const char *dst, char **cmdbuf) 
++static int rsynccmd(const char * src, const char *dst, char **cmdbuf)
+ {
+ 	char *buf = NULL;
+ 	char *newbuf = NULL;
+@@ -559,7 +563,7 @@ static int rsynccmd(const char * src, co
+ 		newbuf = NULL;
+ 	}
+ 
+-	if (buf) { 
++	if (buf) {
+ 		if (asprintf(&newbuf, "/usr/bin/rsync -trlHDq %s '%s'", buf, dst) == -1) {
+ 			fprintf(stderr, "Out of memory\n");
+ 			goto err;
+@@ -674,8 +678,12 @@ static char *create_tmpdir(const char *s
+ 	if (verify_directory(tmpdir, NULL, out_st) < 0) {
+ 		goto err;
+ 	}
+-	if (check_owner_uid(0, tmpdir, out_st) < 0) goto err;
+-	if (check_owner_gid(getgid(), tmpdir, out_st) < 0) goto err;
++
++	if (check_owner_uid(0, tmpdir, out_st) < 0)
++		goto err;
++
++	if (check_owner_gid(getgid(), tmpdir, out_st) < 0)
++		goto err;
+ 
+ 	/* change permissions of the temporary directory */
+ 	if ((fd_t = open(tmpdir, O_RDONLY)) < 0) {
+@@ -702,7 +710,7 @@ static char *create_tmpdir(const char *s
+ 
+ 	/* copy selinux context */
+ 	if (execcon) {
+-		if (fsetfilecon(fd_t, con) == -1) {	
++		if (fsetfilecon(fd_t, con) == -1) {
+ 			fprintf(stderr, _("Failed to set context of the directory %s: %s\n"), tmpdir, strerror(errno));
+ 			goto err;
+ 		}
+@@ -734,12 +742,77 @@ good:
  	return tmpdir;
  }
  
@@ -272,6 +734,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
 +	max_pids = 256;
 +	pid_table = malloc(max_pids * sizeof (pid_t));
 +	if (!pid_table) {
++		(void)closedir(dir);
 +		return -1;
 +	}
 +	pids = 0;
@@ -285,6 +748,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
 +
 +		if (pids == max_pids) {
 +			if (!(pid_table = realloc(pid_table, 2*pids*sizeof(pid_t)))) {
++				(void)closedir(dir);
 +				return -1;
 +			}
 +			max_pids *= 2;
@@ -298,7 +762,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
 +		pid_t id = pid_table[i];
 +
 +		if (getpidcon(id, &scon) == 0) {
-+			
++
 +			context_t pidcon = context_new(scon);
 +			/* Attempt to kill remaining processes */
 +			if (strcmp(context_range_get(pidcon), mcs) == 0)
@@ -325,7 +789,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  
  	char *homedir_s = NULL;	/* homedir spec'd by user in argv[] */
  	char *tmpdir_s = NULL;	/* tmpdir spec'd by user in argv[] */
-@@ -752,9 +834,11 @@ int main(int argc, char **argv) {
+@@ -752,18 +825,21 @@ int main(int argc, char **argv) {
  	const struct option long_options[] = {
  		{"homedir", 1, 0, 'h'},
  		{"tmpdir", 1, 0, 't'},
@@ -337,7 +801,18 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  		{NULL, 0, 0, 0}
  	};
  
-@@ -783,7 +867,7 @@ int main(int argc, char **argv) {
+ 	uid_t uid = getuid();
+-
++/*
+ 	if (!uid) {
+ 		fprintf(stderr, _("Must not be root"));
+ 		return -1;
+ 	}
++*/
+ 
+ #ifdef USE_NLS
+ 	setlocale(LC_ALL, "");
+@@ -783,7 +859,7 @@ int main(int argc, char **argv) {
  	}
  
  	while (1) {
@@ -346,7 +821,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  		if (clflag == -1)
  			break;
  
-@@ -791,6 +875,9 @@ int main(int argc, char **argv) {
+@@ -791,6 +867,9 @@ int main(int argc, char **argv) {
  		case 't':
  			tmpdir_s = optarg;
  			break;
@@ -356,7 +831,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  		case 'h':
  			homedir_s = optarg;
  			break;
-@@ -800,6 +887,9 @@ int main(int argc, char **argv) {
+@@ -800,6 +879,9 @@ int main(int argc, char **argv) {
  		case 'c':
  			usecgroups = 1;
  			break;
@@ -366,7 +841,21 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  		case 'Z':
  			execcon = optarg;
  			break;
-@@ -851,7 +941,7 @@ int main(int argc, char **argv) {
+@@ -824,9 +906,11 @@ int main(int argc, char **argv) {
+ 		return -1;
+ 	}
+ 
+-	if (set_signal_handles()) return -1;
++	if (set_signal_handles())
++		return -1;
+ 
+-	if (usecgroups && setup_cgroups() < 0) return  -1;
++	if (usecgroups && setup_cgroups() < 0)
++		return  -1;
+ 
+ 	/* set fsuid to ruid */
+ 	/* Changing fsuid is usually required when user-specified directory is
+@@ -851,7 +935,7 @@ int main(int argc, char **argv) {
  	}
  
  	/* spawn child process */
@@ -375,7 +864,78 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  	if (child == -1) {
  		perror(_("Unable to fork"));
  		goto err;
-@@ -926,6 +1016,12 @@ childerr:
+@@ -859,6 +943,7 @@ int main(int argc, char **argv) {
+ 
+ 	if (child == 0) {
+ 		char *display = NULL;
++		char *LANG = NULL;
+ 		int rc = -1;
+ 
+ 		if (unshare(CLONE_NEWNS) < 0) {
+@@ -866,6 +951,13 @@ int main(int argc, char **argv) {
+ 			goto childerr;
+ 		}
+ 
++		/* Remount / as SLAVE so that nothing mounted in the namespace 
++		   shows up in the parent */
++		if (mount("none", "/", NULL, MS_SLAVE | MS_REC , NULL) < 0) {
++			perror(_("Failed to make / a SLAVE mountpoint\n"));
++			goto childerr;
++		}
++
+ 		/* assume fsuid==ruid after this point */
+ 		setfsuid(uid);
+ 
+@@ -884,12 +976,23 @@ int main(int argc, char **argv) {
+ 				goto childerr;
+ 			}
+ 		}
++		
++		/* construct a new environment */
++		if ((LANG = getenv("LANG")) != NULL) {
++			if ((LANG = strdup(LANG)) == NULL) {
++				perror(_("Out of memory"));
++				goto childerr;
++			}
++		}
++		
+ 		if ((rc = clearenv()) != 0) {
+ 			perror(_("Failed to clear environment"));
+ 			goto childerr;
+ 		}
+-		if (display) 
++		if (display)
+ 			rc |= setenv("DISPLAY", display, 1);
++		if (LANG) 
++			rc |= setenv("LANG", LANG, 1);
+ 		rc |= setenv("HOME", pwd->pw_dir, 1);
+ 		rc |= setenv("SHELL", pwd->pw_shell, 1);
+ 		rc |= setenv("USER", pwd->pw_name, 1);
+@@ -899,7 +1002,7 @@ int main(int argc, char **argv) {
+ 			fprintf(stderr, _("Failed to construct environment\n"));
+ 			goto childerr;
+ 		}
+-		
++
+ 		/* selinux context */
+ 		if (execcon && setexeccon(execcon) != 0) {
+ 			fprintf(stderr, _("Could not set exec context to %s.\n"), execcon);
+@@ -910,13 +1013,12 @@ int main(int argc, char **argv) {
+ 			perror(_("Failed to change dir to homedir"));
+ 			goto childerr;
+ 		}
+-
+ 		setsid();
+-
+ 		execv(argv[optind], argv + optind);
+ 		fprintf(stderr, _("Failed to execute command %s: %s\n"), argv[optind], strerror(errno));
+ childerr:
+ 		free(display);
++		free(LANG);
+ 		exit(-1);
+ 	}
+ 
+@@ -926,10 +1028,15 @@ childerr:
  	waitpid(child, &status, 0);
  	status_to_retval(status, status);
  
@@ -388,3 +948,7 @@ diff -up policycoreutils-2.0.86/sandbox/seunshare.c.sandbox policycoreutils-2.0.
  	if (tmpdir_r) cleanup_tmpdir(tmpdir_r, tmpdir_s, pwd, 1);
  
  err:
+ 	free(tmpdir_r);
+ 	return status;
+ }
+-
diff --git a/policycoreutils.spec b/policycoreutils.spec
index 9a23a53..9a7e32f 100644
--- a/policycoreutils.spec
+++ b/policycoreutils.spec
@@ -7,7 +7,7 @@
 Summary: SELinux policy core utilities
 Name:	 policycoreutils
 Version: 2.0.86
-Release: 7.2%{?dist}
+Release: 7.3%{?dist}
 License: GPLv2
 Group:	 System Environment/Base
 # Based on git repository with tag 20101221
@@ -334,6 +334,11 @@ fi
 exit 0
 
 %changelog
+* Tue Jan 3 2012 Dan Walsh <dwalsh at redhat.com> - 2.0.86-7.3
+- Fix the handling of namespaces in seunshare/sandbox.
+- Currently mounting of directories within sandbox is propogating to the 
+- parent namesspace.
+
 * Thu Jul 7 2011 Dan Walsh <dwalsh at redhat.com> 2.0.86-7.2
 - Change seunshare to send kill signals to the childs session. 
 - Also add signal handler to catch sigint, so if user enters ctrl-C sandbox will shutdown.


More information about the scm-commits mailing list