[policycoreutils/f15] Change seunshare to send kill signals to the childs session. Also add signal handler to catch sigint

Daniel J Walsh dwalsh at fedoraproject.org
Thu Jul 7 18:48:12 UTC 2011


commit 9f197b5eb0915a09b36c07f435ac8511d2516979
Author: Dan Walsh <dwalsh at redhat.com>
Date:   Thu Jul 7 14:47:56 2011 -0400

    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.
    Add -k qualifier to seunshare to have it attempt to kill all processes with
    the matching MCS label.
    Add -C option to sandbox and seunshare to maintain capabilities, otherwise
    the bounding set will be dropped.
    Change --cgroups short name -c rather then -C for consistancy
    Fix memory and fd leaks in seunshare

 policycoreutils-sandbox.patch |  333 +++++++++++++++++++++++++++++++++++++++--
 policycoreutils.spec          |   12 ++-
 2 files changed, 334 insertions(+), 11 deletions(-)
---
diff --git a/policycoreutils-sandbox.patch b/policycoreutils-sandbox.patch
index a9c61c3..254dd89 100644
--- a/policycoreutils-sandbox.patch
+++ b/policycoreutils-sandbox.patch
@@ -7,9 +7,39 @@ diff -up policycoreutils-2.0.86/restorecond/restorecond_user.conf.sandbox policy
  ~/.cache/*
 -
 +~/.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
+@@ -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
+ 
+ .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
+ .br
+ .SH DESCRIPTION
+ .PP
+@@ -60,8 +60,11 @@ 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\-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
++\fB\-C\fR
++Use capabilities within the sandbox.  By default applications executed within the sandbox will not be allowed to use capabilities (setuid apps), with the -C flag, you can use programs requiring capabilities.
+ .PP
+ .SH "SEE ALSO"
+ .TP
 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-06-13 13:44:45.252092012 -0400
++++ policycoreutils-2.0.86/sandbox/sandbox	2011-07-07 14:42:50.587660702 -0400
 @@ -88,9 +88,7 @@ def copyfile(file, srcdir, dest):
  
                except shutil.Error, elist:
@@ -21,7 +51,22 @@ diff -up policycoreutils-2.0.86/sandbox/sandbox.sandbox policycoreutils-2.0.86/s
                       
                SAVE_FILES[file] = (dest, os.path.getmtime(dest))
  
-@@ -321,7 +319,7 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+@@ -311,17 +309,21 @@ 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",
++        parser.add_option("-c", "--cgroups",
+                          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()
  
          if self.__options.X_ind:
                 self.setype = DEFAULT_X_TYPE
@@ -30,7 +75,21 @@ diff -up policycoreutils-2.0.86/sandbox/sandbox.sandbox policycoreutils-2.0.86/s
          if self.__options.setype:
                 self.setype = self.__options.setype
  
-@@ -405,7 +403,7 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+@@ -392,8 +394,12 @@ sandbox [-h] [-l level ] [-[X|M] [-H hom
+     def __execute(self):
+            try:
+                   cmds = [ SEUNSHARE,  "-Z", self.__execcon ]
+-                  if self.__options.usecgroup == True:
++                  if self.__options.usecgroup:
+                          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
  
                                  self.__setup_sandboxrc(self.__options.wm)
  
@@ -41,12 +100,13 @@ diff -up policycoreutils-2.0.86/sandbox/sandbox.sandbox policycoreutils-2.0.86/s
                           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-06-13 13:44:45.253092023 -0400
-@@ -1,10 +1,11 @@
++++ policycoreutils-2.0.86/sandbox/sandboxX.sh	2011-07-07 14:41:50.536205201 -0400
+@@ -1,10 +1,12 @@
  #!/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"
++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" 
@@ -58,20 +118,273 @@ diff -up policycoreutils-2.0.86/sandbox/sandboxX.sh.sandbox policycoreutils-2.0.
      export DISPLAY=:$D
      cat > ~/seremote << __EOF
  #!/bin/sh
+@@ -13,7 +15,7 @@ __EOF
+     chmod +x ~/seremote
+     /usr/share/sandbox/start $HOME/.sandboxrc
+     export EXITCODE=$?
+-    kill -HUP 0
++    kill -TERM 0
+     break
+ 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 @@
+ 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]
+ .br
+ .SH DESCRIPTION
+ .PP
+@@ -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.
+ .TP
+-\fB\-c cgroups\fR
++\fB\-c --cgroups\fR
+ Use cgroups to control this copy of seunshare.  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
++\fB\-C --capabilities\fR
++Allow apps executed within the namespace to use capabilities.  Default is no capabilities.
++.TP
++\fB\-k --kill\fR
++Kill all processes with matching MCS level.
++.TP
+ \fB\-Z\ context
+ Use alternate SELinux context while runing the executable.
+ .TP
 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-06-13 13:44:45.255092045 -0400
-@@ -63,10 +63,10 @@ static int verbose = 0;
++++ policycoreutils-2.0.86/sandbox/seunshare.c	2011-07-07 14:41:08.038882237 -0400
+@@ -29,6 +29,7 @@
+ 
+ #include <selinux/selinux.h>
+ #include <selinux/context.h>	/* for context-mangling functions */
++#include <dirent.h>
+ 
+ #ifdef USE_NLS
+ #include <locale.h>		/* for setlocale() */
+@@ -53,20 +54,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]")
+ 
+ static int verbose = 0;
++static int child = 0;
+ 
++static capng_select_t cap_set = CAPNG_SELECT_BOTH;
+ 
+ /**
+  * This function will drop all capabilities.
   */
  static int drop_caps()
  {
 -	if (capng_have_capabilities(CAPNG_SELECT_BOTH) == CAPNG_NONE)
-+	if (capng_have_capabilities(CAPNG_SELECT_CAPS) == CAPNG_NONE)
++	if (capng_have_capabilities(cap_set) == CAPNG_NONE)
  		return 0;
 -	capng_clear(CAPNG_SELECT_BOTH);
 -	if (capng_lock() == -1 || capng_apply(CAPNG_SELECT_BOTH) == -1) {
-+	capng_clear(CAPNG_SELECT_CAPS);
-+	if (capng_lock() == -1 || capng_apply(CAPNG_SELECT_CAPS) == -1) {
++	capng_clear(cap_set);
++	if (capng_lock() == -1 || capng_apply(cap_set) == -1) {
  		fprintf(stderr, _("Failed to drop all capabilities\n"));
  		return -1;
  	}
+@@ -86,6 +89,13 @@ static int drop_privs(uid_t uid)
+ }
+ 
+ /**
++ * If the user sends a siginto to seunshare, kill the child's session
++ */
++void handler(int sig) {
++	if (child > 0) kill(-child,sig);
++}
++
++/**
+  * Take care of any signal setup.
+  */
+ static int set_signal_handles(void)
+@@ -101,7 +111,12 @@ 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");
++		return -1;
++	}
++
++	if (signal(SIGINT, handler) == SIG_ERR) {
+ 		perror("Unable to set SIGHUP handler");
+ 		return -1;
+ 	}
+@@ -334,6 +349,7 @@ static int setup_cgroups()
+ 	char buf[BUF_SIZE];
+ 	char *tok = NULL;
+ 	int rc = -1;
++	char *str = NULL;
+ 	const char* fname = "/etc/sysconfig/sandbox";	
+ 	
+ 	if ((fp = fopen(fname, "rt")) == NULL) {
+@@ -346,7 +362,8 @@ static int setup_cgroups()
+ 		
+ 		/* Copy the string, ignoring whitespace */
+ 		int len = strlen(buf);
+-		char *str = malloc((len + 1) * sizeof(char));
++		free(str);
++		str = malloc((len + 1) * sizeof(char));
+ 		
+ 		int ind = 0;	
+ 		int i;
+@@ -487,6 +504,8 @@ static int setup_cgroups()
+ 
+ 	rc = 0;
+ err:
++	fclose(fp);
++	free(str);
+ 	free(mem);
+ 	free(cgroupname);
+ 	free(cpus);
+@@ -734,12 +753,75 @@ good:
+ 	return tmpdir;
+ }
+ 
++#define PROC_BASE "/proc"
++
++static int
++killall (security_context_t execcon)
++{
++	DIR *dir;
++	security_context_t scon;
++	struct dirent *de;
++	pid_t *pid_table, pid, self;
++	int i;
++	int pids, max_pids;
++	int running = 0;
++	self = getpid();
++	if (!(dir = opendir(PROC_BASE))) {
++		return -1;
++	}
++	max_pids = 256;
++	pid_table = malloc(max_pids * sizeof (pid_t));
++	if (!pid_table) {
++		return -1;
++	}
++	pids = 0;
++	context_t con;
++	con = context_new(execcon);
++	const char *mcs = context_range_get(con);
++	printf("mcs=%s\n", mcs);
++	while ((de = readdir (dir)) != NULL) {
++		if (!(pid = (pid_t)atoi(de->d_name)) || pid == self)
++			continue;
++
++		if (pids == max_pids) {
++			if (!(pid_table = realloc(pid_table, 2*pids*sizeof(pid_t)))) {
++				return -1;
++			}
++			max_pids *= 2;
++		}
++		pid_table[pids++] = pid;
++	}
++
++	(void)closedir(dir);
++
++	for (i = 0; i < pids; i++) {
++		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)
++				kill(id, SIGKILL);
++
++			context_free(pidcon);
++			freecon(scon);
++		}
++		running++;
++	}
++
++	context_free(con);
++	free(pid_table);
++	return running;
++}
++
+ int main(int argc, char **argv) {
+ 	int status = -1;
+ 	security_context_t execcon = NULL;
+ 
+ 	int clflag;		/* holds codes for command line flags */
+ 	int usecgroups = 0;
++	int kill_all = 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) {
+ 	const struct option long_options[] = {
+ 		{"homedir", 1, 0, 'h'},
+ 		{"tmpdir", 1, 0, 't'},
++		{"kill", 1, 0, 'k'},
+ 		{"verbose", 1, 0, 'v'},
+ 		{"cgroups", 1, 0, 'c'},
+ 		{"context", 1, 0, 'Z'},
++		{"capabilities", 1, 0, 'C'},
+ 		{NULL, 0, 0, 0}
+ 	};
+ 
+@@ -783,7 +867,7 @@ int main(int argc, char **argv) {
+ 	}
+ 
+ 	while (1) {
+-		clflag = getopt_long(argc, argv, "cvh:t:Z:", long_options, NULL);
++		clflag = getopt_long(argc, argv, "Ccvh:t:Z:", long_options, NULL);
+ 		if (clflag == -1)
+ 			break;
+ 
+@@ -791,6 +875,9 @@ int main(int argc, char **argv) {
+ 		case 't':
+ 			tmpdir_s = optarg;
+ 			break;
++		case 'k':
++			kill_all = 1;
++			break;
+ 		case 'h':
+ 			homedir_s = optarg;
+ 			break;
+@@ -800,6 +887,9 @@ int main(int argc, char **argv) {
+ 		case 'c':
+ 			usecgroups = 1;
+ 			break;
++		case 'C':
++			cap_set = CAPNG_SELECT_CAPS;
++			break;
+ 		case 'Z':
+ 			execcon = optarg;
+ 			break;
+@@ -851,7 +941,7 @@ int main(int argc, char **argv) {
+ 	}
+ 
+ 	/* spawn child process */
+-	int child = fork();
++	child = fork();
+ 	if (child == -1) {
+ 		perror(_("Unable to fork"));
+ 		goto err;
+@@ -926,6 +1016,12 @@ childerr:
+ 	waitpid(child, &status, 0);
+ 	status_to_retval(status, status);
+ 
++	/* Make sure all child processes exit */
++	kill(-child,SIGTERM);
++
++	if (execcon && kill)
++		killall(execcon);
++
+ 	if (tmpdir_r) cleanup_tmpdir(tmpdir_r, tmpdir_s, pwd, 1);
+ 
+ err:
diff --git a/policycoreutils.spec b/policycoreutils.spec
index b5ef4e7..9a23a53 100644
--- a/policycoreutils.spec
+++ b/policycoreutils.spec
@@ -7,7 +7,7 @@
 Summary: SELinux policy core utilities
 Name:	 policycoreutils
 Version: 2.0.86
-Release: 7.1%{?dist}
+Release: 7.2%{?dist}
 License: GPLv2
 Group:	 System Environment/Base
 # Based on git repository with tag 20101221
@@ -334,6 +334,16 @@ fi
 exit 0
 
 %changelog
+* 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.
+- Add -k qualifier to seunshare to have it attempt to kill all processes with 
+the matching MCS label.
+- Add -C option to sandbox and seunshare to maintain capabilities, otherwise 
+the bounding set will be dropped.
+- Change --cgroups short name -c rather then -C for consistancy
+- Fix memory and fd leaks in seunshare
+
 * Mon Jun 13 2011 Dan Walsh <dwalsh at redhat.com> 2.0.86-7.1
 - Do not drop capability bounding set in seunshare, this allows sandbox to 
 - run setuid apps.


More information about the scm-commits mailing list