sandbox: Use temporary directory for XDG_RUNTIME_DIR
XDG_RUNTIME_DIR (/run/user/$UID) is used for user-specific data files such as sockets, named pipes and so on. Therefore, it should not be available to sandboxed processes. Usage: # ls -a $XDG_RUNTIME_DIR . .. bus pipewire-0 systemd # sandbox -R /root/sandbox/user -- sh -c "ls -a $XDG_RUNTIME_DIR" . .. Signed-off-by: Petr Lautrbach <plautrba@redhat.com> Acked-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
parent
0fb988c86b
commit
ecfcb1d6a8
4 changed files with 57 additions and 13 deletions
|
@ -209,6 +209,7 @@ class Sandbox:
|
|||
self.__level = None
|
||||
self.__homedir = None
|
||||
self.__tmpdir = None
|
||||
self.__runuserdir = None
|
||||
|
||||
def __validate_mount(self):
|
||||
if self.__options.level:
|
||||
|
@ -357,6 +358,11 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
|
|||
action="callback", callback=self.__validdir,
|
||||
help=_("alternate /tmp directory to use for mounting"))
|
||||
|
||||
parser.add_option("-R", "--runuserdir", dest="runuserdir",
|
||||
type="string",
|
||||
action="callback", callback=self.__validdir,
|
||||
help=_("alternate XDG_RUNTIME_DIR - /run/user/$UID - directory to use for mounting"))
|
||||
|
||||
parser.add_option("-w", "--windowsize", dest="windowsize",
|
||||
type="string", default=DEFAULT_WINDOWSIZE,
|
||||
help="size of the sandbox window")
|
||||
|
@ -401,10 +407,12 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
|
|||
self.__options.X_ind = True
|
||||
self.__homedir = self.__options.homedir
|
||||
self.__tmpdir = self.__options.tmpdir
|
||||
self.__runuserdir = self.__options.runuserdir
|
||||
else:
|
||||
if self.__options.level:
|
||||
self.__homedir = self.__options.homedir
|
||||
self.__tmpdir = self.__options.tmpdir
|
||||
self.__runuserdir = self.__options.runuserdir
|
||||
|
||||
if len(cmds) == 0:
|
||||
self.usage(_("Command required"))
|
||||
|
@ -442,9 +450,14 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
|
|||
self.__tmpdir = self.__options.tmpdir
|
||||
else:
|
||||
self.__tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_tmp_")
|
||||
if self.__options.runuserdir:
|
||||
self.__runuserdir = self.__options.runuserdir
|
||||
else:
|
||||
self.__runuserdir = mkdtemp(dir="/tmp", prefix=".sandbox_runuser_")
|
||||
self.__copyfiles()
|
||||
selinux.chcon(self.__homedir, self.__filecon, recursive=True)
|
||||
selinux.chcon(self.__tmpdir, self.__filecon, recursive=True)
|
||||
selinux.chcon(self.__runuserdir, self.__filecon, recursive=True)
|
||||
selinux.setfscreatecon(None)
|
||||
|
||||
def __execute(self):
|
||||
|
@ -453,7 +466,7 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
|
|||
if self.__options.usecaps:
|
||||
cmds.append('-C')
|
||||
if self.__mount:
|
||||
cmds += ["-t", self.__tmpdir, "-h", self.__homedir]
|
||||
cmds += ["-t", self.__tmpdir, "-h", self.__homedir, "-r", self.__runuserdir]
|
||||
|
||||
if self.__options.X_ind:
|
||||
if self.__options.dpi:
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
sandbox \- Run cmd under an SELinux sandbox
|
||||
.SH SYNOPSIS
|
||||
.B sandbox
|
||||
[\-C] [\-s] [ \-d DPI ] [\-l level ] [[\-M | \-X] \-H homedir \-T tempdir ] [\-I includefile ] [ \-W windowmanager ] [ \-w windowsize ] [[\-i file ]...] [ \-t type ] cmd
|
||||
[\-C] [\-s] [ \-d DPI ] [\-l level ] [[\-M | \-X] \-H homedir \-T tempdir ] [ \-R runuserdir ] [\-I includefile ] [ \-W windowmanager ] [ \-w windowsize ] [[\-i file ]...] [ \-t type ] cmd
|
||||
|
||||
.br
|
||||
.B sandbox
|
||||
[\-C] [\-s] [ \-d DPI ] [\-l level ] [[\-M | \-X] \-H homedir \-T tempdir ] [\-I includefile ] [ \-W windowmanager ] [ \-w windowsize ] [[\-i file ]...] [ \-t type ] \-S
|
||||
[\-C] [\-s] [ \-d DPI ] [\-l level ] [[\-M | \-X] \-H homedir \-T tempdir ] [ \-R runuserdir ] [\-I includefile ] [ \-W windowmanager ] [ \-w windowsize ] [[\-i file ]...] [ \-t type ] \-S
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
|
@ -67,6 +67,9 @@ sandbox_net_client_t \- All network ports
|
|||
\fB\-T\fR \fB\-\-tmpdir\fR
|
||||
Use alternate temporary directory to mount on /tmp. Defaults to tmpfs. Requires \-X or \-M.
|
||||
.TP
|
||||
\fB\-R\fR \fB\-\-runuserdir\fR
|
||||
Use alternate temporary directory to mount on XDG_RUNTIME_DIR (/run/user/$UID).
|
||||
.TP
|
||||
\fB\-S\fR \fB\-\-session\fR
|
||||
Run a full desktop session, Requires level, and home and tmpdir.
|
||||
.TP
|
||||
|
|
|
@ -18,6 +18,9 @@ Alternate homedir to be used by the application. Homedir must be owned by the u
|
|||
\fB\-t\ tmpdir
|
||||
Use alternate temporary directory to mount on /tmp. tmpdir must be owned by the user.
|
||||
.TP
|
||||
\fB\-r\ runuserdir
|
||||
Use alternate temporary directory to mount on XDG_RUNTIME_DIR (/run/user/$UID). runuserdir must be owned by the user.
|
||||
.TP
|
||||
\fB\-C --capabilities\fR
|
||||
Allow apps executed within the namespace to use capabilities. Default is no capabilities.
|
||||
.TP
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
#define BUF_SIZE 1024
|
||||
#define DEFAULT_PATH "/usr/bin:/bin"
|
||||
#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -C ] [ -k ] [ -t tmpdir ] [ -h homedir ] [ -Z CONTEXT ] -- executable [args] ")
|
||||
#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -C ] [ -k ] [ -t tmpdir ] [ -h homedir ] [ -r runuserdir ] [ -Z CONTEXT ] -- executable [args] ")
|
||||
|
||||
static int verbose = 0;
|
||||
static int child = 0;
|
||||
|
@ -623,15 +623,20 @@ int main(int argc, char **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_r = NULL; /* tmpdir created by seunshare */
|
||||
char *runuserdir_s = NULL; /* /var/run/user/UID spec'd by user in argv[] */
|
||||
char *runuserdir_r = NULL; /* /var/run/user/UID created by seunshare */
|
||||
|
||||
struct stat st_curhomedir;
|
||||
struct stat st_homedir;
|
||||
struct stat st_tmpdir_s;
|
||||
struct stat st_tmpdir_r;
|
||||
struct stat st_runuserdir_s;
|
||||
struct stat st_runuserdir_r;
|
||||
|
||||
const struct option long_options[] = {
|
||||
{"homedir", 1, 0, 'h'},
|
||||
{"tmpdir", 1, 0, 't'},
|
||||
{"runuserdir", 1, 0, 'r'},
|
||||
{"kill", 1, 0, 'k'},
|
||||
{"verbose", 1, 0, 'v'},
|
||||
{"context", 1, 0, 'Z'},
|
||||
|
@ -665,7 +670,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
while (1) {
|
||||
clflag = getopt_long(argc, argv, "Ccvh:t:Z:", long_options, NULL);
|
||||
clflag = getopt_long(argc, argv, "Ccvh:r:t:Z:", long_options, NULL);
|
||||
if (clflag == -1)
|
||||
break;
|
||||
|
||||
|
@ -679,6 +684,9 @@ int main(int argc, char **argv) {
|
|||
case 'h':
|
||||
homedir_s = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
runuserdir_s = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
@ -729,6 +737,10 @@ int main(int argc, char **argv) {
|
|||
if (tmpdir_s && (
|
||||
verify_directory(tmpdir_s, NULL, &st_tmpdir_s) < 0 ||
|
||||
check_owner_uid(uid, tmpdir_s, &st_tmpdir_s))) return -1;
|
||||
if (runuserdir_s && (
|
||||
verify_directory(runuserdir_s, NULL, &st_runuserdir_s) < 0 ||
|
||||
check_owner_uid(uid, runuserdir_s, &st_runuserdir_s))) return -1;
|
||||
|
||||
if ((uid_t)setfsuid(0) != uid) return -1;
|
||||
|
||||
/* create runtime tmpdir */
|
||||
|
@ -737,6 +749,12 @@ int main(int argc, char **argv) {
|
|||
fprintf(stderr, _("Failed to create runtime temporary directory\n"));
|
||||
return -1;
|
||||
}
|
||||
/* create runtime runuserdir */
|
||||
if (runuserdir_s && (runuserdir_r = create_tmpdir(runuserdir_s, &st_runuserdir_s,
|
||||
&st_runuserdir_r, pwd, execcon)) == NULL) {
|
||||
fprintf(stderr, _("Failed to create runtime $XDG_RUNTIME_DIR directory\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* spawn child process */
|
||||
child = fork();
|
||||
|
@ -775,7 +793,21 @@ int main(int argc, char **argv) {
|
|||
if (check_owner_uid(uid, resolved_path, &st_curhomedir) < 0)
|
||||
goto childerr;
|
||||
|
||||
/* mount homedir and tmpdir, in this order */
|
||||
if ((RUNTIME_DIR = getenv("XDG_RUNTIME_DIR")) != NULL) {
|
||||
if ((RUNTIME_DIR = strdup(RUNTIME_DIR)) == NULL) {
|
||||
perror(_("Out of memory"));
|
||||
goto childerr;
|
||||
}
|
||||
} else {
|
||||
if (asprintf(&RUNTIME_DIR, "/run/user/%d", uid) == -1) {
|
||||
perror(_("Out of memory\n"));
|
||||
goto childerr;
|
||||
}
|
||||
}
|
||||
|
||||
/* mount homedir, runuserdir and tmpdir, in this order */
|
||||
if (runuserdir_s && seunshare_mount(runuserdir_s, RUNTIME_DIR,
|
||||
&st_runuserdir_s) != 0) goto childerr;
|
||||
if (homedir_s && seunshare_mount(homedir_s, resolved_path,
|
||||
&st_homedir) != 0) goto childerr;
|
||||
if (tmpdir_s && seunshare_mount(tmpdir_r, "/tmp",
|
||||
|
@ -799,13 +831,6 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((RUNTIME_DIR = getenv("XDG_RUNTIME_DIR")) != NULL) {
|
||||
if ((RUNTIME_DIR = strdup(RUNTIME_DIR)) == NULL) {
|
||||
perror(_("Out of memory"));
|
||||
goto childerr;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rc = clearenv()) != 0) {
|
||||
perror(_("Failed to clear environment"));
|
||||
goto childerr;
|
||||
|
|
Loading…
Reference in a new issue