summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-01-10 20:18:51 +0100
committerGitHub <noreply@github.com>2018-01-10 20:18:51 +0100
commita9883559e3d29246a40973461e57915f4ff4c8ea (patch)
treee6b12732fb88f65b896ad04d418744956de9f4fd /src
parent5a2dadf1bbf4c7c0b04dddee98a3a6b2a053f868 (diff)
parente557b1a655561906343918fa30959b53d16c3fdd (diff)
downloadsystemd-a9883559e3d29246a40973461e57915f4ff4c8ea.tar.gz
Merge pull request #7846 from poettering/nobody-getenv
some assorted fixes and additions, in particular a way to turn off "nobody" synthesizing on a specific system
Diffstat (limited to 'src')
-rw-r--r--src/basic/fileio.c9
-rw-r--r--src/basic/fs-util.h4
-rw-r--r--src/basic/process-util.c2
-rw-r--r--src/basic/rm-rf.h3
-rw-r--r--src/basic/string-util.h6
-rw-r--r--src/basic/user-util.c39
-rw-r--r--src/basic/user-util.h2
-rw-r--r--src/basic/util.c12
-rw-r--r--src/basic/util.h2
-rw-r--r--src/core/job.c3
-rw-r--r--src/core/kill.c3
-rw-r--r--src/core/main.c2
-rw-r--r--src/core/manager.c30
-rw-r--r--src/core/shutdown.c3
-rw-r--r--src/coredump/coredump.c2
-rw-r--r--src/journal/journal-send.c3
-rw-r--r--src/nss-systemd/nss-systemd.c12
-rw-r--r--src/shared/condition.c3
-rw-r--r--src/tmpfiles/tmpfiles.c45
-rw-r--r--src/udev/udev-builtin-input_id.c3
20 files changed, 123 insertions, 65 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index 430851cc8c..26d6174664 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -1225,8 +1225,7 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
if (!filename_is_valid(fn))
return -EINVAL;
- if (!extra)
- extra = "";
+ extra = strempty(extra);
t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
if (!t)
@@ -1259,8 +1258,7 @@ int tempfn_random(const char *p, const char *extra, char **ret) {
if (!filename_is_valid(fn))
return -EINVAL;
- if (!extra)
- extra = "";
+ extra = strempty(extra);
t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
if (!t)
@@ -1300,8 +1298,7 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
return r;
}
- if (!extra)
- extra = "";
+ extra = strempty(extra);
t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
if (!t)
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index a7ba61625d..82a5b2028d 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -29,6 +29,7 @@
#include <unistd.h>
#include "time-util.h"
+#include "util.h"
int unlink_noerrno(const char *path);
@@ -89,13 +90,14 @@ int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flag
/* Useful for usage with _cleanup_(), removes a directory and frees the pointer */
static inline void rmdir_and_free(char *p) {
+ PROTECT_ERRNO;
(void) rmdir(p);
free(p);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
static inline void unlink_and_free(char *p) {
- (void) unlink(p);
+ (void) unlink_noerrno(p);
free(p);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index ce6c0645bb..9fc5464665 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -796,6 +796,8 @@ void sigkill_wait(pid_t pid) {
}
void sigkill_waitp(pid_t *pid) {
+ PROTECT_ERRNO;
+
if (!pid)
return;
if (*pid <= 1)
diff --git a/src/basic/rm-rf.h b/src/basic/rm-rf.h
index 1127e326b2..ad63e9be40 100644
--- a/src/basic/rm-rf.h
+++ b/src/basic/rm-rf.h
@@ -22,6 +22,8 @@
#include <sys/stat.h>
+#include "util.h"
+
typedef enum RemoveFlags {
REMOVE_ONLY_DIRECTORIES = 1,
REMOVE_ROOT = 2,
@@ -34,6 +36,7 @@ int rm_rf(const char *path, RemoveFlags flags);
/* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */
static inline void rm_rf_physical_and_free(char *p) {
+ PROTECT_ERRNO;
(void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
free(p);
}
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index 09a737ad37..d8f97e697b 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -52,15 +52,15 @@ static inline bool streq_ptr(const char *a, const char *b) {
}
static inline const char* strempty(const char *s) {
- return s ? s : "";
+ return s ?: "";
}
static inline const char* strnull(const char *s) {
- return s ? s : "(null)";
+ return s ?: "(null)";
}
static inline const char *strna(const char *s) {
- return s ? s : "n/a";
+ return s ?: "n/a";
}
static inline bool isempty(const char *p) {
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index b99775c18f..17a9b5a8f1 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -137,7 +137,8 @@ int get_user_creds(
return 0;
}
- if (STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
+ if (synthesize_nobody() &&
+ STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
*username = NOBODY_USER_NAME;
if (uid)
@@ -243,7 +244,8 @@ int get_group_creds(const char **groupname, gid_t *gid) {
return 0;
}
- if (STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
+ if (synthesize_nobody() &&
+ STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
*groupname = NOBODY_GROUP_NAME;
if (gid)
@@ -283,7 +285,8 @@ char* uid_to_name(uid_t uid) {
/* Shortcut things to avoid NSS lookups */
if (uid == 0)
return strdup("root");
- if (uid == UID_NOBODY)
+ if (synthesize_nobody() &&
+ uid == UID_NOBODY)
return strdup(NOBODY_USER_NAME);
if (uid_is_valid(uid)) {
@@ -323,7 +326,8 @@ char* gid_to_name(gid_t gid) {
if (gid == 0)
return strdup("root");
- if (gid == GID_NOBODY)
+ if (synthesize_nobody() &&
+ gid == GID_NOBODY)
return strdup(NOBODY_GROUP_NAME);
if (gid_is_valid(gid)) {
@@ -427,7 +431,8 @@ int get_home_dir(char **_h) {
*_h = h;
return 0;
}
- if (u == UID_NOBODY) {
+ if (synthesize_nobody() &&
+ u == UID_NOBODY) {
h = strdup("/");
if (!h)
return -ENOMEM;
@@ -482,7 +487,8 @@ int get_shell(char **_s) {
*_s = s;
return 0;
}
- if (u == UID_NOBODY) {
+ if (synthesize_nobody() &&
+ u == UID_NOBODY) {
s = strdup("/sbin/nologin");
if (!s)
return -ENOMEM;
@@ -690,3 +696,24 @@ int maybe_setgroups(size_t size, const gid_t *list) {
return 0;
}
+
+bool synthesize_nobody(void) {
+
+#ifdef NOLEGACY
+ return true;
+#else
+ /* Returns true when we shall synthesize the "nobody" user (which we do by default). This can be turned off by
+ * touching /etc/systemd/dont-synthesize-nobody in order to provide upgrade compatibility with legacy systems
+ * that used the "nobody" user name and group name for other UIDs/GIDs than 65534.
+ *
+ * Note that we do not employ any kind of synchronization on the following caching variable. If the variable is
+ * accessed in multi-threaded programs in the worst case it might happen that we initialize twice, but that
+ * shouldn't matter as each initialization should come to the same result. */
+ static int cache = -1;
+
+ if (cache < 0)
+ cache = access("/etc/systemd/dont-synthesize-nobody", F_OK) < 0;
+
+ return cache;
+#endif
+}
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
index 79adf91ee9..5f0391f2b8 100644
--- a/src/basic/user-util.h
+++ b/src/basic/user-util.h
@@ -97,3 +97,5 @@ bool valid_gecos(const char *d);
bool valid_home(const char *p);
int maybe_setgroups(size_t size, const gid_t *list);
+
+bool synthesize_nobody(void);
diff --git a/src/basic/util.c b/src/basic/util.c
index b1e6f5002e..2d31d84165 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -618,7 +618,13 @@ int str_verscmp(const char *s1, const char *s2) {
}
/* Turn off core dumps but only if we're running outside of a container. */
-void disable_core_dumps(void) {
- if (detect_container() <= 0)
- (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+void disable_coredumps(void) {
+ int r;
+
+ if (detect_container() > 0)
+ return;
+
+ r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+ if (r < 0)
+ log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
}
diff --git a/src/basic/util.h b/src/basic/util.h
index c10cfea952..9d1b10756b 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -192,4 +192,4 @@ int version(void);
int str_verscmp(const char *s1, const char *s2);
-void disable_core_dumps(void);
+void disable_coredumps(void);
diff --git a/src/core/job.c b/src/core/job.c
index b046698118..c6de8d27e4 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -306,8 +306,7 @@ void job_dump(Job *j, FILE*f, const char *prefix) {
assert(j);
assert(f);
- if (!prefix)
- prefix = "";
+ prefix = strempty(prefix);
fprintf(f,
"%s-> Job %u:\n"
diff --git a/src/core/kill.c b/src/core/kill.c
index f438c4d8fa..5dfcb780fa 100644
--- a/src/core/kill.c
+++ b/src/core/kill.c
@@ -34,8 +34,7 @@ void kill_context_init(KillContext *c) {
void kill_context_dump(KillContext *c, FILE *f, const char *prefix) {
assert(c);
- if (!prefix)
- prefix = "";
+ prefix = strempty(prefix);
fprintf(f,
"%sKillMode: %s\n"
diff --git a/src/core/main.c b/src/core/main.c
index 712f1d39b5..c850f6f904 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1607,7 +1607,7 @@ static void initialize_coredump(bool skip_setup) {
/* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
* until the systemd-coredump tool is enabled via sysctl. */
if (!skip_setup)
- disable_core_dumps();
+ disable_coredumps();
}
static void do_reexecute(
diff --git a/src/core/manager.c b/src/core/manager.c
index 860d58617f..a9c4330897 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -513,23 +513,31 @@ static int manager_setup_signals(Manager *m) {
return 0;
}
-static void manager_clean_environment(Manager *m) {
+static void manager_sanitize_environment(Manager *m) {
assert(m);
- /* Let's remove some environment variables that we
- * need ourselves to communicate with our clients */
+ /* Let's remove some environment variables that we need ourselves to communicate with our clients */
strv_env_unset_many(
m->environment,
- "NOTIFY_SOCKET",
+ "EXIT_CODE",
+ "EXIT_STATUS",
+ "INVOCATION_ID",
+ "JOURNAL_STREAM",
+ "LISTEN_FDNAMES",
+ "LISTEN_FDS",
+ "LISTEN_PID",
"MAINPID",
"MANAGERPID",
- "LISTEN_PID",
- "LISTEN_FDS",
- "LISTEN_FDNAMES",
+ "NOTIFY_SOCKET",
+ "REMOTE_ADDR",
+ "REMOTE_PORT",
+ "SERVICE_RESULT",
"WATCHDOG_PID",
"WATCHDOG_USEC",
- "INVOCATION_ID",
NULL);
+
+ /* Let's order the environment alphabetically, just to make it pretty */
+ strv_sort(m->environment);
}
static int manager_default_environment(Manager *m) {
@@ -556,8 +564,7 @@ static int manager_default_environment(Manager *m) {
if (!m->environment)
return -ENOMEM;
- manager_clean_environment(m);
- strv_sort(m->environment);
+ manager_sanitize_environment(m);
return 0;
}
@@ -3308,8 +3315,7 @@ int manager_environment_add(Manager *m, char **minus, char **plus) {
strv_free(b);
m->environment = l;
- manager_clean_environment(m);
- strv_sort(m->environment);
+ manager_sanitize_environment(m);
return 0;
}
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index da817c898d..fb882db99b 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -333,8 +333,7 @@ int main(int argc, char *argv[]) {
if (!in_container)
sync_with_progress();
- /* Prevent coredumps */
- disable_core_dumps();
+ disable_coredumps();
log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true, arg_timeout);
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index f83a951df7..fdcea22f56 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -1126,7 +1126,7 @@ static int gather_pid_metadata(
/* If this is PID 1 disable coredump collection, we'll unlikely be able to process it later on. */
if (is_pid1_crash((const char**) context)) {
log_notice("Due to PID 1 having crashed coredump collection will now be turned off.");
- disable_core_dumps();
+ disable_coredumps();
}
set_iovec_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]);
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index a78aa07032..b322127a4e 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -418,8 +418,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
fd_inc_sndbuf(fd, SNDBUF_SIZE);
- if (!identifier)
- identifier = "";
+ identifier = strempty(identifier);
l = strlen(identifier);
header = alloca(l + 1 + 1 + 2 + 2 + 2 + 2 + 2);
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
index cc641e1615..f75405d2e5 100644
--- a/src/nss-systemd/nss-systemd.c
+++ b/src/nss-systemd/nss-systemd.c
@@ -136,7 +136,8 @@ enum nss_status _nss_systemd_getpwnam_r(
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
- if (streq(name, nobody_passwd.pw_name)) {
+ if (synthesize_nobody() &&
+ streq(name, nobody_passwd.pw_name)) {
*pwd = nobody_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
@@ -244,7 +245,8 @@ enum nss_status _nss_systemd_getpwuid_r(
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
- if (uid == nobody_passwd.pw_uid) {
+ if (synthesize_nobody() &&
+ uid == nobody_passwd.pw_uid) {
*pwd = nobody_passwd;
*errnop = 0;
return NSS_STATUS_SUCCESS;
@@ -351,7 +353,8 @@ enum nss_status _nss_systemd_getgrnam_r(
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
- if (streq(name, nobody_group.gr_name)) {
+ if (synthesize_nobody() &&
+ streq(name, nobody_group.gr_name)) {
*gr = nobody_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
@@ -456,7 +459,8 @@ enum nss_status _nss_systemd_getgrgid_r(
*errnop = 0;
return NSS_STATUS_SUCCESS;
}
- if (gid == nobody_group.gr_gid) {
+ if (synthesize_nobody() &&
+ gid == nobody_group.gr_gid) {
*gr = nobody_group;
*errnop = 0;
return NSS_STATUS_SUCCESS;
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 7a825c3973..a2fd05c425 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -653,8 +653,7 @@ void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_
assert(c);
assert(f);
- if (!prefix)
- prefix = "";
+ prefix = strempty(prefix);
fprintf(f,
"%s\t%s: %s%s%s %s\n",
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index a7ce1a8049..d69073535c 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -375,35 +375,47 @@ static struct Item* find_glob(OrderedHashmap *h, const char *match) {
static void load_unix_sockets(void) {
_cleanup_fclose_ FILE *f = NULL;
- char line[LINE_MAX];
+ int r;
if (unix_sockets)
return;
- /* We maintain a cache of the sockets we found in
- * /proc/net/unix to speed things up a little. */
+ /* We maintain a cache of the sockets we found in /proc/net/unix to speed things up a little. */
unix_sockets = set_new(&string_hash_ops);
if (!unix_sockets)
return;
f = fopen("/proc/net/unix", "re");
- if (!f)
- return;
+ if (!f) {
+ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
+ "Failed to open /proc/net/unix, ignoring: %m");
+ goto fail;
+ }
/* Skip header */
- if (!fgets(line, sizeof(line), f))
+ r = read_line(f, LONG_LINE_MAX, NULL);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to skip /proc/net/unix header line: %m");
+ goto fail;
+ }
+ if (r == 0) {
+ log_warning("Premature end of file reading /proc/net/unix.");
goto fail;
+ }
for (;;) {
+ _cleanup_free_ char *line = NULL;
char *p, *s;
- int k;
- if (!fgets(line, sizeof(line), f))
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to read /proc/net/unix line, ignoring: %m");
+ goto fail;
+ }
+ if (r == 0) /* EOF */
break;
- truncate_nl(line);
-
p = strchr(line, ':');
if (!p)
continue;
@@ -420,21 +432,24 @@ static void load_unix_sockets(void) {
continue;
s = strdup(p);
- if (!s)
+ if (!s) {
+ log_oom();
goto fail;
+ }
path_kill_slashes(s);
- k = set_consume(unix_sockets, s);
- if (k < 0 && k != -EEXIST)
+ r = set_consume(unix_sockets, s);
+ if (r < 0 && r != -EEXIST) {
+ log_warning_errno(r, "Failed to add AF_UNIX socket to set, ignoring: %m");
goto fail;
+ }
}
return;
fail:
- set_free_free(unix_sockets);
- unix_sockets = NULL;
+ unix_sockets = set_free_free(unix_sockets);
}
static bool unix_socket_alive(const char *fn) {
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index b13fdb135b..fa830213ff 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -102,8 +102,7 @@ static void get_cap_mask(struct udev_device *dev,
unsigned long val;
v = udev_device_get_sysattr_value(pdev, attr);
- if (!v)
- v = "";
+ v = strempty(v);
xsprintf(text, "%s", v);
log_debug("%s raw kernel attribute: %s", attr, text);