[policycoreutils] 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:37:37 UTC 2011


commit af0f4926da918604124f6394d14060ed9fd50210
Author: Dan Walsh <dwalsh at redhat.com>
Date:   Thu Jul 7 14:37:24 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.

 policycoreutils-rhat.patch |  199 ++++++++++++++++++++++++++++++++------------
 policycoreutils.spec       |   14 +++-
 2 files changed, 158 insertions(+), 55 deletions(-)
---
diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch
index aa5b05c..986eff0 100644
--- a/policycoreutils-rhat.patch
+++ b/policycoreutils-rhat.patch
@@ -1664,7 +1664,7 @@ index ff0ee7c..0c8a085 100644
  test:
  	@python test_sandbox.py -v
 diff --git a/policycoreutils/sandbox/sandbox b/policycoreutils/sandbox/sandbox
-index 48a26c2..41a3204 100644
+index 48a26c2..4d17385 100644
 --- a/policycoreutils/sandbox/sandbox
 +++ b/policycoreutils/sandbox/sandbox
 @@ -1,5 +1,6 @@
@@ -1869,7 +1869,7 @@ index 48a26c2..41a3204 100644
                 if len(cmds) == 0:
                        self.usage(_("Command required"))
                 cmds[0] = fullpath(cmds[0])
-@@ -329,44 +374,45 @@ sandbox [-h] [-[X|M] [-l level ] [-H homedir] [-T tempdir]] [-I includefile ] [-
+@@ -329,44 +374,47 @@ sandbox [-h] [-[X|M] [-l level ] [-H homedir] [-T tempdir]] [-I includefile ] [-
      def __setup_dir(self):
             if self.__options.level or self.__options.session:
                    return
@@ -1910,10 +1910,12 @@ index 48a26c2..41a3204 100644
 -                         return rc
 -
 +                  cmds = [ SEUNSHARE,  "-Z", self.__execcon ]
-+                  if self.__options.usecgroup == True:
++                  if self.__options.usecgroup:
 +                         cmds.append('-c')
-+                  if self.__options.usecaps == True:
++                  if self.__options.usecaps:
 +                         cmds.append('-C')
++                  if not self.__options.level:
++                         cmds.append('-k')
                    if self.__mount:
 -                         cmds =  [ '/usr/sbin/seunshare', "-t", self.__tmpdir, "-h", self.__homedir, "--", self.__execcon ] + self.__paths
 -                         rc = subprocess.Popen(cmds).wait()
@@ -1935,7 +1937,7 @@ index 48a26c2..41a3204 100644
  
                    selinux.setexeccon(self.__execcon)
                    rc = subprocess.Popen(self.__cmds).wait()
-@@ -404,7 +450,7 @@ if __name__ == '__main__':
+@@ -404,7 +452,7 @@ if __name__ == '__main__':
             sandbox = Sandbox()
             rc = sandbox.main()
      except OSError, error:
@@ -2104,11 +2106,12 @@ index ff8b3ef..66aadfd 100644
  }
  
 diff --git a/policycoreutils/sandbox/sandboxX.sh b/policycoreutils/sandbox/sandboxX.sh
-index 8338203..9648100 100644
+index 8338203..0b0239c 100644
 --- a/policycoreutils/sandbox/sandboxX.sh
 +++ b/policycoreutils/sandbox/sandboxX.sh
-@@ -1,13 +1,18 @@
+@@ -1,15 +1,21 @@
  #!/bin/bash 
++trap "" TERM
  context=`id -Z | secon -t -l -P`
  export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8-80`"
 -export SCREENSIZE="1000x700"
@@ -2128,20 +2131,23 @@ index 8338203..9648100 100644
 +    chmod +x ~/seremote
 +    /usr/share/sandbox/start $HOME/.sandboxrc
      export EXITCODE=$?
-     kill -HUP 0
+-    kill -HUP 0
++    kill -TERM 0
      break
+ done
+ exit 0
 diff --git a/policycoreutils/sandbox/seunshare.8 b/policycoreutils/sandbox/seunshare.8
 new file mode 100644
-index 0000000..eeb2218
+index 0000000..c69ceda
 --- /dev/null
 +++ b/policycoreutils/sandbox/seunshare.8
-@@ -0,0 +1,40 @@
+@@ -0,0 +1,43 @@
 +.TH SEUNSHARE "8" "May 2010" "seunshare" "User Commands"
 +.SH NAME
 +seunshare \- Run cmd with alternate homedir, tmpdir and/or SELinux context
 +.SH SYNOPSIS
 +.B seunshare
-+[ -v ] [-c] [-C] [ -t tmpdir ] [ -h homedir ] [ -Z context ] -- executable [args]
++[-v] [-c] [-C] [-k] [ -t tmpdir ] [ -h homedir ] [ -Z context ] -- executable [args]
 +.br
 +.SH DESCRIPTION
 +.PP
@@ -2162,6 +2168,9 @@ index 0000000..eeb2218
 +\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
@@ -2177,10 +2186,10 @@ index 0000000..eeb2218
 +and
 +.I Thomas Liu <tliu at fedoraproject.org>
 diff --git a/policycoreutils/sandbox/seunshare.c b/policycoreutils/sandbox/seunshare.c
-index ec692e7..e3fa6bd 100644
+index ec692e7..431271f 100644
 --- a/policycoreutils/sandbox/seunshare.c
 +++ b/policycoreutils/sandbox/seunshare.c
-@@ -1,28 +1,35 @@
+@@ -1,27 +1,35 @@
 +/*
 + * Authors: Dan Walsh <dwalsh at redhat.com>
 + * Authors: Thomas Liu <tliu at fedoraproject.org>
@@ -2213,15 +2222,15 @@ index ec692e7..e3fa6bd 100644
  
  #include <selinux/selinux.h>
  #include <selinux/context.h>	/* for context-mangling functions */
- 
+-
 -#include <sys/types.h>
 -#include <sys/stat.h>
 -#include <unistd.h>
--
++#include <dirent.h>
+ 
  #ifdef USE_NLS
  #include <locale.h>		/* for setlocale() */
- #include <libintl.h>		/* for gettext() */
-@@ -39,29 +46,48 @@
+@@ -39,29 +47,56 @@
  #define MS_PRIVATE 1<<18
  #endif
  
@@ -2235,6 +2244,7 @@ index ec692e7..e3fa6bd 100644
 +#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;
 +
@@ -2249,23 +2259,19 @@ index ec692e7..e3fa6bd 100644
 -	capng_clear(CAPNG_SELECT_BOTH);
 -
 -	if (capng_lock() < 0) 
--		return -1;
--	/* Change uid */
--	if (setresuid(uid, uid, uid)) {
--		fprintf(stderr, _("Error changing uid, aborting.\n"));
 +	if (capng_have_capabilities(cap_set) == CAPNG_NONE)
 +		return 0;
 +	capng_clear(cap_set);
 +	if (capng_lock() == -1 || capng_apply(cap_set) == -1) {
 +		fprintf(stderr, _("Failed to drop all capabilities\n"));
  		return -1;
- 	}
--	return capng_apply(CAPNG_SELECT_BOTH);
+-	/* Change uid */
+-	if (setresuid(uid, uid, uid)) {
+-		fprintf(stderr, _("Error changing uid, aborting.\n"));
++	}
 +	return 0;
- }
- 
--#define DEFAULT_PATH "/usr/bin:/bin"
--static	int verbose = 0;
++}
++
 +/**
 + * This function will drop all privileges.
 + */
@@ -2273,9 +2279,19 @@ index ec692e7..e3fa6bd 100644
 +{
 +	if (drop_caps() == -1 || setresuid(uid, uid, uid) == -1) {
 +		fprintf(stderr, _("Failed to drop privileges\n"));
-+		return -1;
-+	}
+ 		return -1;
+ 	}
+-	return capng_apply(CAPNG_SELECT_BOTH);
 +	return 0;
+ }
+ 
+-#define DEFAULT_PATH "/usr/bin:/bin"
+-static	int verbose = 0;
++/**
++ * If the user sends a siginto to seunshare, kill the child's session
++ */
++void handler(int sig) {
++	if (child > 0) kill(-child,sig);
 +}
  
  /**
@@ -2284,21 +2300,25 @@ index ec692e7..e3fa6bd 100644
   */
  static int set_signal_handles(void)
  {
-@@ -75,8 +101,8 @@ static int set_signal_handles(void)
+@@ -75,32 +110,117 @@ static int set_signal_handles(void)
  
  	(void)sigprocmask(SIG_SETMASK, &empty, NULL);
  
 -	/* Terminate on SIGHUP. */
--	if (signal(SIGHUP, SIG_DFL) == SIG_ERR) {
 +	/* 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;
  	}
-@@ -84,23 +110,103 @@ static int set_signal_handles(void)
- 	return 0;
- }
  
++	if (signal(SIGINT, handler) == SIG_ERR) {
++		perror("Unable to set SIGHUP handler");
++		return -1;
++	}
++
++	return 0;
++}
++
 +#define status_to_retval(status,retval) do { \
 +	if ((status) == -1) \
 +		retval = -1; \
@@ -2365,9 +2385,9 @@ index ec692e7..e3fa6bd 100644
 +		fprintf(stderr, _("Error: %s not owned by GID %d\n"), file, gid);
 +		return -1;
 +	}
-+	return 0;
-+}
-+
+ 	return 0;
+ }
+ 
 +#define equal_stats(one,two) \
 +	((one)->st_dev == (two)->st_dev && (one)->st_ino == (two)->st_ino && \
 +	 (one)->st_uid == (two)->st_uid && (one)->st_gid == (two)->st_gid && \
@@ -2409,7 +2429,7 @@ index ec692e7..e3fa6bd 100644
  	return 0;
  }
  
-@@ -123,7 +229,7 @@ static int verify_shell(const char *shell_name)
+@@ -123,7 +243,7 @@ static int verify_shell(const char *shell_name)
  
  		/* check the shell skipping newline char */
  		if (!strcmp(shell_name, buf)) {
@@ -2418,7 +2438,7 @@ index ec692e7..e3fa6bd 100644
  			break;
  		}
  	}
-@@ -131,45 +237,530 @@ static int verify_shell(const char *shell_name)
+@@ -131,45 +251,594 @@ static int verify_shell(const char *shell_name)
  	return rc;
  }
  
@@ -2817,9 +2837,8 @@ index ec692e7..e3fa6bd 100644
 +	setfsuid(pwd->pw_uid);
 +
 +	return 0;
- }
- 
--#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -t tmpdir ] [ -h homedir ] -- CONTEXT executable [args] ")
++}
++
 +/**
 + * seunshare will create a tmpdir in /tmp, with root ownership.  The parent
 + * process waits for it child to exit to attempt to remove the directory.  If
@@ -2931,6 +2950,69 @@ index ec692e7..e3fa6bd 100644
 +	if (fd_t >= 0) close(fd_t);
 +	if (fd_s >= 0) close(fd_s);
 +	return tmpdir;
+ }
+ 
+-#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -t tmpdir ] [ -h homedir ] -- CONTEXT executable [args] ")
++#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) {
@@ -2944,6 +3026,7 @@ index ec692e7..e3fa6bd 100644
  	int clflag;		/* holds codes for command line flags */
 -	char *tmpdir_s = NULL;	/* tmpdir spec'd by user in argv[] */
 +	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[] */
@@ -2956,6 +3039,7 @@ index ec692e7..e3fa6bd 100644
  	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'},
@@ -2963,7 +3047,7 @@ index ec692e7..e3fa6bd 100644
  		{NULL, 0, 0, 0}
  	};
  
-@@ -180,6 +771,12 @@ int main(int argc, char **argv) {
+@@ -180,6 +849,12 @@ int main(int argc, char **argv) {
  		return -1;
  	}
  
@@ -2976,7 +3060,7 @@ index ec692e7..e3fa6bd 100644
  	struct passwd *pwd=getpwuid(uid);
  	if (!pwd) {
  		perror(_("getpwduid failed"));
-@@ -187,34 +784,33 @@ int main(int argc, char **argv) {
+@@ -187,34 +862,36 @@ int main(int argc, char **argv) {
  	}
  
  	if (verify_shell(pwd->pw_shell) < 0) {
@@ -3000,6 +3084,9 @@ index ec692e7..e3fa6bd 100644
 -			}
 -			if (verify_mount(tmpdir_s, pwd) < 0) return -1;
 +			tmpdir_s = optarg;
++			break;
++		case 'k':
++			kill_all = 1;
  			break;
  		case 'h':
 -			if (!(homedir_s = realpath(optarg, NULL))) {
@@ -3025,7 +3112,7 @@ index ec692e7..e3fa6bd 100644
  			break;
  		default:
  			fprintf(stderr, "%s\n", USAGE_STRING);
-@@ -223,76 +819,84 @@ int main(int argc, char **argv) {
+@@ -223,76 +900,84 @@ int main(int argc, char **argv) {
  	}
  
  	if (! homedir_s && ! tmpdir_s) {
@@ -3067,9 +3154,6 @@ index ec692e7..e3fa6bd 100644
 -		if (tmpdir_s && seunshare_mount(tmpdir_s, "/tmp", pwd) < 0)
 -				return -1;
 -	}
--
--	if (drop_capabilities(uid)) {
--		perror(_("Failed to drop all capabilities"));
 +	if (set_signal_handles()) return -1;
 +
 +	if (usecgroups && setup_cgroups() < 0) return  -1;
@@ -3088,7 +3172,9 @@ index ec692e7..e3fa6bd 100644
 +		verify_directory(tmpdir_s, NULL, &st_tmpdir_s) < 0 ||
 +		check_owner_uid(uid, tmpdir_s, &st_tmpdir_s))) return -1;
 +	setfsuid(0);
-+
+ 
+-	if (drop_capabilities(uid)) {
+-		perror(_("Failed to drop all capabilities"));
 +	/* create runtime tmpdir */
 +	if (tmpdir_s && (tmpdir_r = create_tmpdir(tmpdir_s, &st_tmpdir_s,
 +						  &st_tmpdir_r, pwd, execcon)) == NULL) {
@@ -3096,8 +3182,9 @@ index ec692e7..e3fa6bd 100644
  		return -1;
  	}
  
+-	int child = fork();
 +	/* spawn child process */
- 	int child = fork();
++	child = fork();
  	if (child == -1) {
  		perror(_("Unable to fork"));
 -		return -1;
@@ -3159,7 +3246,7 @@ index ec692e7..e3fa6bd 100644
  		if (display) 
  			rc |= setenv("DISPLAY", display, 1);
  		rc |= setenv("HOME", pwd->pw_dir, 1);
-@@ -300,22 +904,41 @@ int main(int argc, char **argv) {
+@@ -300,22 +985,47 @@ int main(int argc, char **argv) {
  		rc |= setenv("USER", pwd->pw_name, 1);
  		rc |= setenv("LOGNAME", pwd->pw_name, 1);
  		rc |= setenv("PATH", DEFAULT_PATH, 1);
@@ -3195,10 +3282,16 @@ index ec692e7..e3fa6bd 100644
 -	free(tmpdir_s);
 -	free(homedir_s);
 +	drop_caps();
- 
++
 +	/* parent waits for child exit to do the cleanup */
 +	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);
 +
diff --git a/policycoreutils.spec b/policycoreutils.spec
index 944a90b..365c37e 100644
--- a/policycoreutils.spec
+++ b/policycoreutils.spec
@@ -7,7 +7,7 @@
 Summary: SELinux policy core utilities
 Name:	 policycoreutils
 Version: 2.0.86
-Release: 15%{?dist}
+Release: 18%{?dist}
 License: GPLv2
 Group:	 System Environment/Base
 # Based on git repository with tag 20101221
@@ -349,7 +349,17 @@ fi
 /bin/systemctl try-restart restorecond.service >/dev/null 2>&1 || :
 
 %changelog
-* Mon Jul 5 2011 Dan Walsh <dwalsh at redhat.com> 2.0.86-16
+* Thu Jul 7 2011 Dan Walsh <dwalsh at redhat.com> 2.0.86-18
+- 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.
+
+* Wed Jul 6 2011 Dan Walsh <dwalsh at redhat.com> 2.0.86-17
+- Add -k qualifier to seunshare to have it attempt to kill all processes with 
+the matching MCS label.
+sandbox will default to using the -k, if the level was not specified.
+This is added to make sure all processes are killed with the sandbox exits.
+
+* Tue Jul 5 2011 Dan Walsh <dwalsh at redhat.com> 2.0.86-16
 - 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


More information about the scm-commits mailing list