mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-06 13:17:44 +03:00
Make PrivateTmp dirs also inaccessible from the outside
Currently, PrivateTmp=yes means that the service cannot see the /tmp shared by rest of the system and is isolated from other services using PrivateTmp, but users can access and modify /tmp as seen by the service. Move the private /tmp and /var/tmp directories into a 0077-mode directory. This way unpriviledged users on the system cannot see (or modify) /tmp as seen by the service.
This commit is contained in:
parent
1f048a6b6b
commit
d34cd37490
@ -40,6 +40,7 @@
|
|||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <linux/seccomp-bpf.h>
|
#include <linux/seccomp-bpf.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
#ifdef HAVE_PAM
|
||||||
#include <security/pam_appl.h>
|
#include <security/pam_appl.h>
|
||||||
@ -1551,19 +1552,22 @@ void exec_context_init(ExecContext *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void exec_context_tmp_dirs_done(ExecContext *c) {
|
void exec_context_tmp_dirs_done(ExecContext *c) {
|
||||||
assert(c);
|
char* dirs[] = {c->tmp_dir ? c->tmp_dir : c->var_tmp_dir,
|
||||||
|
c->tmp_dir ? c->var_tmp_dir : NULL,
|
||||||
|
NULL};
|
||||||
|
char **dirp;
|
||||||
|
|
||||||
if (c->tmp_dir) {
|
for(dirp = dirs; *dirp; dirp++) {
|
||||||
rm_rf_dangerous(c->tmp_dir, false, true, false);
|
char *dir;
|
||||||
free(c->tmp_dir);
|
rm_rf_dangerous(*dirp, false, true, false);
|
||||||
c->tmp_dir = NULL;
|
|
||||||
|
dir = dirname(*dirp);
|
||||||
|
rmdir(dir);
|
||||||
|
|
||||||
|
free(*dirp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->var_tmp_dir) {
|
c->tmp_dir = c->var_tmp_dir = NULL;
|
||||||
rm_rf_dangerous(c->var_tmp_dir, false, true, false);
|
|
||||||
free(c->var_tmp_dir);
|
|
||||||
c->var_tmp_dir = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void exec_context_done(ExecContext *c, bool reloading_or_reexecuting) {
|
void exec_context_done(ExecContext *c, bool reloading_or_reexecuting) {
|
||||||
|
@ -183,22 +183,20 @@ int setup_tmpdirs(char **tmp_dir,
|
|||||||
assert(tmp_dir);
|
assert(tmp_dir);
|
||||||
assert(var_tmp_dir);
|
assert(var_tmp_dir);
|
||||||
|
|
||||||
r = create_tmp_dir(tmp_dir_template, 0000, true, tmp_dir);
|
r = create_tmp_dir(tmp_dir_template, tmp_dir);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail2;
|
return r;
|
||||||
|
|
||||||
r = create_tmp_dir(var_tmp_dir_template, 0000, true, var_tmp_dir);
|
|
||||||
if (r < 0)
|
|
||||||
goto fail1;
|
|
||||||
|
|
||||||
|
r = create_tmp_dir(var_tmp_dir_template, var_tmp_dir);
|
||||||
|
if (r == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail1:
|
/* failure */
|
||||||
rmdir(*tmp_dir);
|
rmdir(*tmp_dir);
|
||||||
|
rmdir(tmp_dir_template);
|
||||||
free(*tmp_dir);
|
free(*tmp_dir);
|
||||||
*tmp_dir = NULL;
|
*tmp_dir = NULL;
|
||||||
|
|
||||||
fail2:
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5683,46 +5683,49 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *sear
|
|||||||
return search_and_fopen_internal(path, mode, s, _f);
|
return search_and_fopen_internal(path, mode, s, _f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_tmp_dir(char template[], mode_t mask, bool need_sticky, char** dir_name) {
|
int create_tmp_dir(char template[], char** dir_name) {
|
||||||
int r = 0;
|
int r = 0;
|
||||||
char *d = NULL;
|
char *d, *dt;
|
||||||
bool remove = false;
|
|
||||||
mode_t _cleanup_umask_ u;
|
mode_t _cleanup_umask_ u;
|
||||||
|
|
||||||
assert(dir_name);
|
assert(dir_name);
|
||||||
|
|
||||||
u = umask(mask);
|
u = umask(0077);
|
||||||
d = mkdtemp(template);
|
d = mkdtemp(template);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
r = -errno;
|
log_error("Can't create directory %s: %m", template);
|
||||||
log_debug("Can't create directory");
|
return -errno;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remove = true;
|
dt = strjoin(d, "/tmp", NULL);
|
||||||
|
if (!dt) {
|
||||||
log_debug("Created temporary directory : %s", template);
|
|
||||||
|
|
||||||
d = strdup(template);
|
|
||||||
if (!d) {
|
|
||||||
r = log_oom();
|
r = log_oom();
|
||||||
goto fail;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_sticky) {
|
umask(0000);
|
||||||
r = chmod(template, 0777 | S_ISVTX);
|
r = mkdir(dt, 0777);
|
||||||
if (r < 0) {
|
if (r) {
|
||||||
|
log_error("Can't create directory %s: %m", dt);
|
||||||
r = -errno;
|
r = -errno;
|
||||||
goto fail;
|
goto fail1;
|
||||||
}
|
|
||||||
log_debug("Setting sticky bit on : %s", template);
|
|
||||||
}
|
}
|
||||||
|
log_debug("Created temporary directory %s", dt);
|
||||||
|
|
||||||
*dir_name = d;
|
r = chmod(dt, 0777 | S_ISVTX);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to chmod %s: %m", dt);
|
||||||
|
r = -errno;
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
log_debug("Set sticky bit on %s", dt);
|
||||||
|
|
||||||
|
*dir_name = dt;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail1:
|
||||||
if (remove)
|
rmdir(dt);
|
||||||
|
fail2:
|
||||||
rmdir(template);
|
rmdir(template);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -579,7 +579,7 @@ int on_ac_power(void);
|
|||||||
|
|
||||||
int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f);
|
int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f);
|
||||||
int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f);
|
int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f);
|
||||||
int create_tmp_dir(char template[], mode_t mask, bool need_sticky, char** dir_name);
|
int create_tmp_dir(char template[], char** dir_name);
|
||||||
|
|
||||||
#define FOREACH_LINE(line, f, on_error) \
|
#define FOREACH_LINE(line, f, on_error) \
|
||||||
for (;;) \
|
for (;;) \
|
||||||
|
@ -12,5 +12,7 @@ d /tmp 1777 root root 10d
|
|||||||
d /var/tmp 1777 root root 30d
|
d /var/tmp 1777 root root 30d
|
||||||
|
|
||||||
# Exclude namespace mountpoints created with PrivateTmp=yes
|
# Exclude namespace mountpoints created with PrivateTmp=yes
|
||||||
X /tmp/systemd-private-*
|
x /tmp/systemd-private-*
|
||||||
X /var/tmp/systemd-private-*
|
x /var/tmp/systemd-private-*
|
||||||
|
X /tmp/systemd-private-*/tmp
|
||||||
|
X /var/tmp/systemd-private-*/tmp
|
||||||
|
Loading…
Reference in New Issue
Block a user