policycoreutils: sandbox: add level based kill option
add kill option to seunshare to kill all processes that are still running with the execcon MCS label. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
f37a6a71cb
commit
e8575bf497
|
@ -3,7 +3,7 @@
|
||||||
seunshare \- Run cmd with alternate homedir, tmpdir and/or SELinux context
|
seunshare \- Run cmd with alternate homedir, tmpdir and/or SELinux context
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B seunshare
|
.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
|
.br
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
|
@ -24,6 +24,9 @@ Use cgroups to control this copy of seunshare. Specify parameters in /etc/sysco
|
||||||
\fB\-C --capabilities\fR
|
\fB\-C --capabilities\fR
|
||||||
Allow apps executed within the namespace to use capabilities. Default is no capabilities.
|
Allow apps executed within the namespace to use capabilities. Default is no capabilities.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-k --kill\fR
|
||||||
|
Kill all processes with matching MCS level.
|
||||||
|
.TP
|
||||||
\fB\-Z\ context
|
\fB\-Z\ context
|
||||||
Use alternate SELinux context while runing the executable.
|
Use alternate SELinux context while runing the executable.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <selinux/selinux.h>
|
#include <selinux/selinux.h>
|
||||||
#include <selinux/context.h> /* for context-mangling functions */
|
#include <selinux/context.h> /* for context-mangling functions */
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#ifdef USE_NLS
|
#ifdef USE_NLS
|
||||||
#include <locale.h> /* for setlocale() */
|
#include <locale.h> /* for setlocale() */
|
||||||
|
@ -43,7 +44,7 @@
|
||||||
|
|
||||||
#define BUF_SIZE 1024
|
#define BUF_SIZE 1024
|
||||||
#define DEFAULT_PATH "/usr/bin:/bin"
|
#define DEFAULT_PATH "/usr/bin:/bin"
|
||||||
#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 verbose = 0;
|
||||||
|
|
||||||
|
@ -735,12 +736,77 @@ good:
|
||||||
return tmpdir;
|
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) {
|
||||||
|
(void)closedir(dir);
|
||||||
|
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)))) {
|
||||||
|
(void)closedir(dir);
|
||||||
|
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 main(int argc, char **argv) {
|
||||||
int status = -1;
|
int status = -1;
|
||||||
security_context_t execcon = NULL;
|
security_context_t execcon = NULL;
|
||||||
|
|
||||||
int clflag; /* holds codes for command line flags */
|
int clflag; /* holds codes for command line flags */
|
||||||
int usecgroups = 0;
|
int usecgroups = 0;
|
||||||
|
int kill_all = 0;
|
||||||
|
|
||||||
char *homedir_s = NULL; /* homedir spec'd by user in argv[] */
|
char *homedir_s = NULL; /* homedir spec'd by user in argv[] */
|
||||||
char *tmpdir_s = NULL; /* tmpdir spec'd by user in argv[] */
|
char *tmpdir_s = NULL; /* tmpdir spec'd by user in argv[] */
|
||||||
|
@ -753,6 +819,7 @@ int main(int argc, char **argv) {
|
||||||
const struct option long_options[] = {
|
const struct option long_options[] = {
|
||||||
{"homedir", 1, 0, 'h'},
|
{"homedir", 1, 0, 'h'},
|
||||||
{"tmpdir", 1, 0, 't'},
|
{"tmpdir", 1, 0, 't'},
|
||||||
|
{"kill", 1, 0, 'k'},
|
||||||
{"verbose", 1, 0, 'v'},
|
{"verbose", 1, 0, 'v'},
|
||||||
{"cgroups", 1, 0, 'c'},
|
{"cgroups", 1, 0, 'c'},
|
||||||
{"context", 1, 0, 'Z'},
|
{"context", 1, 0, 'Z'},
|
||||||
|
@ -788,6 +855,9 @@ int main(int argc, char **argv) {
|
||||||
case 't':
|
case 't':
|
||||||
tmpdir_s = optarg;
|
tmpdir_s = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'k':
|
||||||
|
kill_all = 1;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
homedir_s = optarg;
|
homedir_s = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -926,6 +996,9 @@ childerr:
|
||||||
waitpid(child, &status, 0);
|
waitpid(child, &status, 0);
|
||||||
status_to_retval(status, status);
|
status_to_retval(status, status);
|
||||||
|
|
||||||
|
if (execcon && kill_all)
|
||||||
|
killall(execcon);
|
||||||
|
|
||||||
if (tmpdir_r) cleanup_tmpdir(tmpdir_r, tmpdir_s, pwd, 1);
|
if (tmpdir_r) cleanup_tmpdir(tmpdir_r, tmpdir_s, pwd, 1);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
Loading…
Reference in New Issue