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.
#include <sys/poll.h>
#include <linux/seccomp-bpf.h>
#include <glob.h>
#include <sys/poll.h>
#include <linux/seccomp-bpf.h>
#include <glob.h>
#ifdef HAVE_PAM
#include <security/pam_appl.h>
#ifdef HAVE_PAM
#include <security/pam_appl.h>
}
void exec_context_tmp_dirs_done(ExecContext *c) {
}
void exec_context_tmp_dirs_done(ExecContext *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) {
- rm_rf_dangerous(c->tmp_dir, false, true, false);
- free(c->tmp_dir);
- c->tmp_dir = NULL;
- }
+ for(dirp = dirs; *dirp; dirp++) {
+ char *dir;
+ rm_rf_dangerous(*dirp, false, true, false);
- if (c->var_tmp_dir) {
- rm_rf_dangerous(c->var_tmp_dir, false, true, false);
- free(c->var_tmp_dir);
- c->var_tmp_dir = NULL;
+ dir = dirname(*dirp);
+ rmdir(dir);
+
+ free(*dirp);
+
+ c->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) {
assert(tmp_dir);
assert(var_tmp_dir);
assert(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);
- r = create_tmp_dir(var_tmp_dir_template, 0000, true, var_tmp_dir);
- if (r < 0)
- goto fail1;
-
- return 0;
+ r = create_tmp_dir(var_tmp_dir_template, var_tmp_dir);
+ if (r == 0)
+ return 0;
+ rmdir(tmp_dir_template);
free(*tmp_dir);
*tmp_dir = NULL;
free(*tmp_dir);
*tmp_dir = NULL;
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) {
- char *d = NULL;
- bool remove = false;
mode_t _cleanup_umask_ u;
assert(dir_name);
mode_t _cleanup_umask_ u;
assert(dir_name);
d = mkdtemp(template);
if (!d) {
d = mkdtemp(template);
if (!d) {
- r = -errno;
- log_debug("Can't create directory");
- goto fail;
+ log_error("Can't create directory %s: %m", template);
+ return -errno;
- remove = true;
-
- log_debug("Created temporary directory : %s", template);
-
- d = strdup(template);
- if (!d) {
+ dt = strjoin(d, "/tmp", NULL);
+ if (!dt) {
- if (need_sticky) {
- r = chmod(template, 0777 | S_ISVTX);
- if (r < 0) {
- r = -errno;
- goto fail;
- }
- log_debug("Setting sticky bit on : %s", template);
+ umask(0000);
+ r = mkdir(dt, 0777);
+ if (r) {
+ log_error("Can't create directory %s: %m", dt);
+ r = -errno;
+ goto fail1;
+ }
+ log_debug("Created temporary directory %s", dt);
+
+ 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);
-fail:
- if (remove)
- rmdir(template);
+fail1:
+ rmdir(dt);
+fail2:
+ rmdir(template);
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(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) \
for (;;) \
#define FOREACH_LINE(line, f, on_error) \
for (;;) \
d /var/tmp 1777 root root 30d
# Exclude namespace mountpoints created with PrivateTmp=yes
d /var/tmp 1777 root root 30d
# Exclude namespace mountpoints created with PrivateTmp=yes
-X /tmp/systemd-private-*
-X /var/tmp/systemd-private-*
+x /tmp/systemd-private-*
+x /var/tmp/systemd-private-*
+X /tmp/systemd-private-*/tmp
+X /var/tmp/systemd-private-*/tmp