From 0ae26f6d841adaec76776c2ee2a288f4a5104803 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Feb 15 2013 09:17:57 +0000 Subject: Selected fixes. Resolves: #891667, #876654, #902483, #875653 --- diff --git a/0586-add-log_oom.patch b/0586-add-log_oom.patch new file mode 100644 index 0000000..5b0920f --- /dev/null +++ b/0586-add-log_oom.patch @@ -0,0 +1,52 @@ +From ed460fda887c1704c7969c8d5dc50fad1518de56 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 15 Feb 2013 09:43:12 +0100 +Subject: [PATCH] add log_oom() + +taken from current upstream +--- + src/shared/log.c | 5 +++++ + src/shared/log.h | 7 +++++++ + 2 files changed, 12 insertions(+) + +diff --git a/src/shared/log.c b/src/shared/log.c +index 4ec7b8f..fb15ad0 100644 +--- a/src/shared/log.c ++++ b/src/shared/log.c +@@ -643,6 +643,11 @@ _noreturn_ void log_assert_failed_unreachable(const char *text, const char *file + log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); + } + ++int log_oom_internal(const char *file, int line, const char *func) { ++ log_meta(LOG_ERR, file, line, func, "Out of memory."); ++ return -ENOMEM; ++} ++ + int log_set_target_from_string(const char *e) { + LogTarget t; + +diff --git a/src/shared/log.h b/src/shared/log.h +index daea8b4..b59e763 100644 +--- a/src/shared/log.h ++++ b/src/shared/log.h +@@ -87,6 +87,11 @@ int log_metav( + _noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func); + _noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func); + ++int log_oom_internal( ++ const char *file, ++ int line, ++ const char *func); ++ + /* This modifies the buffer passed! */ + int log_dump_internal( + int level, +@@ -103,6 +108,8 @@ int log_dump_internal( + #define log_warning(...) log_meta(LOG_WARNING, __FILE__, __LINE__, __func__, __VA_ARGS__) + #define log_error(...) log_meta(LOG_ERR, __FILE__, __LINE__, __func__, __VA_ARGS__) + ++#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__) ++ + /* This modifies the buffer passed! */ + #define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer) + diff --git a/0587-add-_cleanup_free_-_cleanup_close_.patch b/0587-add-_cleanup_free_-_cleanup_close_.patch new file mode 100644 index 0000000..f4ebae5 --- /dev/null +++ b/0587-add-_cleanup_free_-_cleanup_close_.patch @@ -0,0 +1,56 @@ +From fdfcc9bf1c66283e2031caaf78a32aa6684a8c46 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 15 Feb 2013 09:36:58 +0100 +Subject: [PATCH] add _cleanup_free_, _cleanup_close_ + +part of upstream commit 2fbe635a83a79f8889afec421ae3990ea106fb91 +--- + src/shared/macro.h | 3 +++ + src/shared/util.c | 9 +++++++++ + src/shared/util.h | 4 ++++ + 3 files changed, 16 insertions(+) + +diff --git a/src/shared/macro.h b/src/shared/macro.h +index 2572a96..f82df89 100644 +--- a/src/shared/macro.h ++++ b/src/shared/macro.h +@@ -188,6 +188,9 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { + return k; + } + ++#define _cleanup_free_ __attribute__((cleanup(freep))) ++#define _cleanup_fclose_ __attribute__((cleanup(fclosep))) ++ + #include "log.h" + + #endif +diff --git a/src/shared/util.c b/src/shared/util.c +index faf428f..c41b9e0 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -5781,3 +5781,12 @@ bool in_initrd(void) { + + return saved; + } ++ ++void freep(void *p) { ++ free(*(void**) p); ++} ++ ++void fclosep(FILE **f) { ++ if (*f) ++ fclose(*f); ++} +diff --git a/src/shared/util.h b/src/shared/util.h +index 5459810..81392f5 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -542,4 +542,8 @@ _malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b) + + return memdup(p, a * b); + } ++ ++void freep(void *p); ++void fclosep(FILE **f); ++ + #endif diff --git a/0588-mount-only-run-fsck-for-actual-device-nodes.patch b/0588-mount-only-run-fsck-for-actual-device-nodes.patch new file mode 100644 index 0000000..386f464 --- /dev/null +++ b/0588-mount-only-run-fsck-for-actual-device-nodes.patch @@ -0,0 +1,36 @@ +From 9c3fe9a304a7da69cc3150f0fbfcb3fc9a749159 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 24 Sep 2012 12:39:13 +0200 +Subject: [PATCH] mount: only run fsck for actual device nodes (cherry picked + from commit 63a8b2f947ad77c464acac475be84682065a6522) + +Conflicts: + src/core/mount.c +--- + src/core/mount.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 5eba12c..05cbaba 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -436,7 +436,8 @@ static int mount_add_device_links(Mount *m) { + + if (!mount_is_bind(p) && + !path_equal(m->where, "/") && +- p == &m->parameters_etc_fstab) { ++ p == &m->parameters_etc_fstab && ++ is_device_path(p->what)) { + bool nofail, noauto; + + noauto = !!mount_test_option(p->options, "noauto"); +@@ -451,7 +452,8 @@ static int mount_add_device_links(Mount *m) { + if (p->passno > 0 && + !mount_is_bind(p) && + UNIT(m)->manager->running_as == MANAGER_SYSTEM && +- !path_equal(m->where, "/")) { ++ !path_equal(m->where, "/") && ++ is_device_path(p->what)) { + char *name; + Unit *fsck; + /* Let's add in the fsck service */ diff --git a/0589-main-bump-up-RLIMIT_NOFILE-for-systemd-itself.patch b/0589-main-bump-up-RLIMIT_NOFILE-for-systemd-itself.patch new file mode 100644 index 0000000..3924fd8 --- /dev/null +++ b/0589-main-bump-up-RLIMIT_NOFILE-for-systemd-itself.patch @@ -0,0 +1,105 @@ +From c057fa6b16c7b05c4b114df3d4e1cbb118b21507 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 17 Sep 2012 16:35:59 +0200 +Subject: [PATCH] main: bump up RLIMIT_NOFILE for systemd itself + +For setups with many listening sockets the default kernel resource limit +of 1024 fds is not enough. Bump this up to 64K to avoid any limitations +in this regard. We are careful to pass on the kernel default to daemons +however, since normally resource limits are a good to enforce, +especially since select() can't handle fds > 1023. +(cherry picked from commit 4096d6f5879aef73e20dd7b62a01f447629945b0) + +Conflicts: + src/core/main.c +--- + src/core/main.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 47 insertions(+), 1 deletion(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 06f14c3..000de93 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1145,6 +1145,42 @@ fail: + return r; + } + ++static int bump_rlimit_nofile(struct rlimit *saved_rlimit) { ++ struct rlimit nl; ++ int r; ++ ++ assert(saved_rlimit); ++ ++ /* Save the original RLIMIT_NOFILE so that we can reset it ++ * later when transitioning from the initrd to the main ++ * systemd or suchlike. */ ++ if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) { ++ log_error("Reading RLIMIT_NOFILE failed: %m"); ++ return -errno; ++ } ++ ++ /* Make sure forked processes get the default kernel setting */ ++ if (!arg_default_rlimit[RLIMIT_NOFILE]) { ++ struct rlimit *rl; ++ ++ rl = newdup(struct rlimit, saved_rlimit, 1); ++ if (!rl) ++ return log_oom(); ++ ++ arg_default_rlimit[RLIMIT_NOFILE] = rl; ++ } ++ ++ /* Bump up the resource limit for ourselves substantially */ ++ nl.rlim_cur = nl.rlim_max = 64*1024; ++ r = setrlimit_closest(RLIMIT_NOFILE, &nl); ++ if (r < 0) { ++ log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r)); ++ return r; ++ } ++ ++ return 0; ++} ++ + static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) { + const char *e; + unsigned long long a, b; +@@ -1227,6 +1263,7 @@ int main(int argc, char *argv[]) { + bool arm_reboot_watchdog = false; + bool queue_default_job = false; + char *switch_root_dir = NULL, *switch_root_init = NULL; ++ static struct rlimit saved_rlimit_nofile = { 0, 0 }; + + #ifdef HAVE_SYSV_COMPAT + if (getpid() != 1 && strstr(program_invocation_short_name, "init")) { +@@ -1519,6 +1556,9 @@ int main(int argc, char *argv[]) { + } + } + ++ if (arg_running_as == MANAGER_SYSTEM) ++ bump_rlimit_nofile(&saved_rlimit_nofile); ++ + r = manager_new(arg_running_as, &m); + if (r < 0) { + log_error("Failed to allocate manager object: %s", strerror(-r)); +@@ -1702,7 +1742,7 @@ finish: + manager_free(m); + + for (j = 0; j < RLIMIT_NLIMITS; j++) +- free (arg_default_rlimit[j]); ++ free(arg_default_rlimit[j]); + + free(arg_default_unit); + strv_free(arg_default_controllers); +@@ -1720,6 +1760,12 @@ finish: + * rebooted while we do that */ + watchdog_close(true); + ++ /* Reset the RLIMIT_NOFILE to the kernel default, so ++ * that the new systemd can pass the kernel default to ++ * its child processes */ ++ if (saved_rlimit_nofile.rlim_cur > 0) ++ setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile); ++ + if (switch_root_dir) { + r = switch_root(switch_root_dir); + if (r < 0) diff --git a/0590-shared-libsystemd-daemon-check-for-empty-strings-in-.patch b/0590-shared-libsystemd-daemon-check-for-empty-strings-in-.patch new file mode 100644 index 0000000..defd353 --- /dev/null +++ b/0590-shared-libsystemd-daemon-check-for-empty-strings-in-.patch @@ -0,0 +1,93 @@ +From 2338f242f613c931f40b8f56d5d1cb82b0ead39b Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 30 Oct 2012 10:29:40 +0100 +Subject: [PATCH] shared, libsystemd-daemon: check for empty strings in strto*l + conversions + +strtol() and friends may set EINVAL if no conversion was performed, but +they are not required to do so. In practice they don't. We need to check +for it. + +https://bugzilla.redhat.com/show_bug.cgi?id=870577 +(cherry picked from commit f3910003bce32ebdc1dbb71fd9ca2d4b8352b563) +--- + src/libsystemd-daemon/sd-daemon.c | 4 ++-- + src/shared/conf-parser.c | 2 +- + src/shared/util.c | 8 ++++---- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/libsystemd-daemon/sd-daemon.c b/src/libsystemd-daemon/sd-daemon.c +index 763e079..78d156c 100644 +--- a/src/libsystemd-daemon/sd-daemon.c ++++ b/src/libsystemd-daemon/sd-daemon.c +@@ -88,7 +88,7 @@ _sd_export_ int sd_listen_fds(int unset_environment) { + goto finish; + } + +- if (!p || *p || l <= 0) { ++ if (!p || p == e || *p || l <= 0) { + r = -EINVAL; + goto finish; + } +@@ -112,7 +112,7 @@ _sd_export_ int sd_listen_fds(int unset_environment) { + goto finish; + } + +- if (!p || *p) { ++ if (!p || p == e || *p) { + r = -EINVAL; + goto finish; + } +diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c +index 24a853c..ea444f7 100644 +--- a/src/shared/conf-parser.c ++++ b/src/shared/conf-parser.c +@@ -863,7 +863,7 @@ int config_parse_mode( + + errno = 0; + l = strtol(rvalue, &x, 8); +- if (!x || *x || errno) { ++ if (!x || x == rvalue || *x || errno) { + log_error("[%s:%u] Failed to parse mode value, ignoring: %s", filename, line, rvalue); + return 0; + } +diff --git a/src/shared/util.c b/src/shared/util.c +index c41b9e0..11f1ea7 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -350,7 +350,7 @@ int safe_atou(const char *s, unsigned *ret_u) { + errno = 0; + l = strtoul(s, &x, 0); + +- if (!x || *x || errno) ++ if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + if ((unsigned long) (unsigned) l != l) +@@ -370,7 +370,7 @@ int safe_atoi(const char *s, int *ret_i) { + errno = 0; + l = strtol(s, &x, 0); + +- if (!x || *x || errno) ++ if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + if ((long) (int) l != l) +@@ -390,7 +390,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { + errno = 0; + l = strtoull(s, &x, 0); + +- if (!x || *x || errno) ++ if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_llu = l; +@@ -407,7 +407,7 @@ int safe_atolli(const char *s, long long int *ret_lli) { + errno = 0; + l = strtoll(s, &x, 0); + +- if (!x || *x || errno) ++ if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_lli = l; diff --git a/0591-shared-core-do-not-always-accept-numbers-in-string-l.patch b/0591-shared-core-do-not-always-accept-numbers-in-string-l.patch new file mode 100644 index 0000000..b197cda --- /dev/null +++ b/0591-shared-core-do-not-always-accept-numbers-in-string-l.patch @@ -0,0 +1,405 @@ +From e9624bbb0d3cf879a2fcd81c0b56cd0e867d0529 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 30 Oct 2012 14:29:38 +0100 +Subject: [PATCH] shared, core: do not always accept numbers in string lookups + +The behaviour of the common name##_from_string conversion is surprising. +It accepts not only the strings from name##_table but also any number +that falls within the range of the table. The order of items in most of +our tables is an internal affair. It should not be visible to the user. + +I know of a case where the surprising numeric conversion leads to a crash. + +We will allow the direct numeric conversion only for the tables where the +mapping of strings to numeric values has an external meaning. This holds +for the following lookup tables: + - netlink_family, ioprio_class, ip_tos, sched_policy - their numeric + values are stable as they are defined by the Linux kernel interface. + - log_level, log_facility_unshifted - the well-known syslog interface. + +We allow the user to use numeric values whose string names systemd does +not know. For instance, the user may want to test a new kernel featuring +a scheduling policy that did not exist when his systemd version was +released. A slightly unpleasant effect of this is that the +name##_to_string conversion cannot return pointers to constant strings +anymore. The strings have to be allocated on demand and freed by the +caller. +(cherry picked from commit f8b69d1dfc307562a353f6aa923b7c2b915aaddb) +--- + src/core/dbus-manager.c | 12 ++++++++---- + src/core/execute.c | 44 +++++++++++++++++++++++++++++++++++++------- + src/core/load-fragment.c | 16 +++++++++------- + src/shared/socket-util.c | 26 ++++++++++---------------- + src/shared/socket-util.h | 2 +- + src/shared/util.c | 10 +++++----- + src/shared/util.h | 48 +++++++++++++++++++++++++++++++++++++++--------- + 7 files changed, 109 insertions(+), 49 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 47d753e..b795530 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -355,17 +355,21 @@ static int bus_manager_set_log_target(DBusMessageIter *i, const char *property, + } + + static int bus_manager_append_log_level(DBusMessageIter *i, const char *property, void *data) { +- const char *t; ++ char *t; ++ int r; + + assert(i); + assert(property); + +- t = log_level_to_string(log_get_max_level()); ++ r = log_level_to_string_alloc(log_get_max_level(), &t); ++ if (r < 0) ++ return r; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) +- return -ENOMEM; ++ r = -ENOMEM; + +- return 0; ++ free(t); ++ return r; + } + + static int bus_manager_set_log_level(DBusMessageIter *i, const char *property, void *data) { +diff --git a/src/core/execute.c b/src/core/execute.c +index 931a9b0..453df3b 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1693,21 +1693,37 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { + if (c->rlimit[i]) + fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max); + +- if (c->ioprio_set) ++ if (c->ioprio_set) { ++ char *class_str; ++ int r; ++ ++ r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str); ++ if (r < 0) ++ class_str = NULL; + fprintf(f, + "%sIOSchedulingClass: %s\n" + "%sIOPriority: %i\n", +- prefix, ioprio_class_to_string(IOPRIO_PRIO_CLASS(c->ioprio)), ++ prefix, strna(class_str), + prefix, (int) IOPRIO_PRIO_DATA(c->ioprio)); ++ free(class_str); ++ } + +- if (c->cpu_sched_set) ++ if (c->cpu_sched_set) { ++ char *policy_str; ++ int r; ++ ++ r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str); ++ if (r < 0) ++ policy_str = NULL; + fprintf(f, + "%sCPUSchedulingPolicy: %s\n" + "%sCPUSchedulingPriority: %i\n" + "%sCPUSchedulingResetOnFork: %s\n", +- prefix, sched_policy_to_string(c->cpu_sched_policy), ++ prefix, strna(policy_str), + prefix, c->cpu_sched_priority, + prefix, yes_no(c->cpu_sched_reset_on_fork)); ++ free(policy_str); ++ } + + if (c->cpuset) { + fprintf(f, "%sCPUAffinity:", prefix); +@@ -1742,12 +1758,26 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { + if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL || + c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE || + c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL || +- c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) ++ c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) { ++ char *fac_str, *lvl_str; ++ int r; ++ ++ r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str); ++ if (r < 0) ++ fac_str = NULL; ++ ++ r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str); ++ if (r < 0) ++ lvl_str = NULL; ++ + fprintf(f, + "%sSyslogFacility: %s\n" + "%sSyslogLevel: %s\n", +- prefix, log_facility_unshifted_to_string(c->syslog_priority >> 3), +- prefix, log_level_to_string(LOG_PRI(c->syslog_priority))); ++ prefix, strna(fac_str), ++ prefix, strna(lvl_str)); ++ free(lvl_str); ++ free(fac_str); ++ } + + if (c->capabilities) { + char *t; +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 9fa749f..c028b78 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -655,7 +655,8 @@ int config_parse_exec_io_class( + assert(rvalue); + assert(data); + +- if ((x = ioprio_class_from_string(rvalue)) < 0) { ++ x = ioprio_class_from_string(rvalue); ++ if (x < 0) { + log_error("[%s:%u] Failed to parse IO scheduling class, ignoring: %s", filename, line, rvalue); + return 0; + } +@@ -714,7 +715,8 @@ int config_parse_exec_cpu_sched_policy( + assert(rvalue); + assert(data); + +- if ((x = sched_policy_from_string(rvalue)) < 0) { ++ x = sched_policy_from_string(rvalue); ++ if (x < 0) { + log_error("[%s:%u] Failed to parse CPU scheduling policy, ignoring: %s", filename, line, rvalue); + return 0; + } +@@ -1487,11 +1489,11 @@ int config_parse_ip_tos( + assert(rvalue); + assert(data); + +- if ((x = ip_tos_from_string(rvalue)) < 0) +- if (safe_atoi(rvalue, &x) < 0) { +- log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue); +- return 0; +- } ++ x = ip_tos_from_string(rvalue); ++ if (x < 0) { ++ log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue); ++ return 0; ++ } + + *ip_tos = x; + return 0; +diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c +index c9963cd..fa54e54 100644 +--- a/src/shared/socket-util.c ++++ b/src/shared/socket-util.c +@@ -193,7 +193,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { + int socket_address_parse_netlink(SocketAddress *a, const char *s) { + int family; + unsigned group = 0; +- char* sfamily = NULL; ++ _cleanup_free_ char *sfamily = NULL; + assert(a); + assert(s); + +@@ -204,13 +204,9 @@ int socket_address_parse_netlink(SocketAddress *a, const char *s) { + if (sscanf(s, "%ms %u", &sfamily, &group) < 1) + return errno ? -errno : -EINVAL; + +- if ((family = netlink_family_from_string(sfamily)) < 0) +- if (safe_atoi(sfamily, &family) < 0) { +- free(sfamily); +- return -EINVAL; +- } +- +- free(sfamily); ++ family = netlink_family_from_string(sfamily); ++ if (family < 0) ++ return -EINVAL; + + a->sockaddr.nl.nl_family = AF_NETLINK; + a->sockaddr.nl.nl_groups = group; +@@ -366,15 +362,13 @@ int socket_address_print(const SocketAddress *a, char **p) { + } + + case AF_NETLINK: { +- const char *sfamily; +- +- if ((sfamily = netlink_family_to_string(a->protocol))) +- r = asprintf(p, "%s %u", sfamily, a->sockaddr.nl.nl_groups); +- else +- r = asprintf(p, "%i %u", a->protocol, a->sockaddr.nl.nl_groups); ++ char *sfamily; + ++ r = netlink_family_to_string_alloc(a->protocol, &sfamily); + if (r < 0) +- return -ENOMEM; ++ return r; ++ r = asprintf(p, "%s %u", sfamily, a->sockaddr.nl.nl_groups); ++ free(sfamily); + + return 0; + } +@@ -539,7 +533,7 @@ static const char* const netlink_family_table[] = { + [NETLINK_ECRYPTFS] = "ecryptfs" + }; + +-DEFINE_STRING_TABLE_LOOKUP(netlink_family, int); ++DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX); + + static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = { + [SOCKET_ADDRESS_DEFAULT] = "default", +diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h +index 8ccbd37..6562a75 100644 +--- a/src/shared/socket-util.h ++++ b/src/shared/socket-util.h +@@ -94,7 +94,7 @@ bool socket_address_needs_mount(const SocketAddress *a, const char *prefix); + const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b); + SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s); + +-const char* netlink_family_to_string(int b); ++int netlink_family_to_string_alloc(int b, char **s); + int netlink_family_from_string(const char *s); + + bool socket_ipv6_is_supported(void); +diff --git a/src/shared/util.c b/src/shared/util.c +index 11f1ea7..5c54e6b 100644 +--- a/src/shared/util.c ++++ b/src/shared/util.c +@@ -5242,7 +5242,7 @@ static const char *const ioprio_class_table[] = { + [IOPRIO_CLASS_IDLE] = "idle" + }; + +-DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int); ++DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX); + + static const char *const sigchld_code_table[] = { + [CLD_EXITED] = "exited", +@@ -5278,7 +5278,7 @@ static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = { + [LOG_FAC(LOG_LOCAL7)] = "local7" + }; + +-DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int); ++DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0)); + + static const char *const log_level_table[] = { + [LOG_EMERG] = "emerg", +@@ -5291,7 +5291,7 @@ static const char *const log_level_table[] = { + [LOG_DEBUG] = "debug" + }; + +-DEFINE_STRING_TABLE_LOOKUP(log_level, int); ++DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG); + + static const char* const sched_policy_table[] = { + [SCHED_OTHER] = "other", +@@ -5301,7 +5301,7 @@ static const char* const sched_policy_table[] = { + [SCHED_RR] = "rr" + }; + +-DEFINE_STRING_TABLE_LOOKUP(sched_policy, int); ++DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); + + static const char* const rlimit_table[] = { + [RLIMIT_CPU] = "LimitCPU", +@@ -5331,7 +5331,7 @@ static const char* const ip_tos_table[] = { + [IPTOS_LOWCOST] = "low-cost", + }; + +-DEFINE_STRING_TABLE_LOOKUP(ip_tos, int); ++DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); + + static const char *const __signal_table[] = { + [SIGHUP] = "HUP", +diff --git a/src/shared/util.h b/src/shared/util.h +index 81392f5..a3f6d9f 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -288,6 +288,7 @@ int make_null_stdio(void); + + unsigned long long random_ull(void); + ++/* For basic lookup tables with strictly enumerated entries */ + #define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ + scope const char *name##_to_string(type i) { \ + if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \ +@@ -296,15 +297,11 @@ unsigned long long random_ull(void); + } \ + scope type name##_from_string(const char *s) { \ + type i; \ +- unsigned u = 0; \ + assert(s); \ + for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \ + if (name##_table[i] && \ + streq(name##_table[i], s)) \ + return i; \ +- if (safe_atou(s, &u) >= 0 && \ +- u < ELEMENTSOF(name##_table)) \ +- return (type) u; \ + return (type) -1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ +@@ -312,6 +309,39 @@ unsigned long long random_ull(void); + #define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,) + #define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static) + ++/* For string conversions where numbers are also acceptable */ ++#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \ ++ int name##_to_string_alloc(type i, char **str) { \ ++ char *s; \ ++ int r; \ ++ if (i < 0 || i > max) \ ++ return -ERANGE; \ ++ if (i < (type) ELEMENTSOF(name##_table)) { \ ++ s = strdup(name##_table[i]); \ ++ if (!s) \ ++ return log_oom(); \ ++ } else { \ ++ r = asprintf(&s, "%u", i); \ ++ if (r < 0) \ ++ return log_oom(); \ ++ } \ ++ *str = s; \ ++ return 0; \ ++ } \ ++ type name##_from_string(const char *s) { \ ++ type i; \ ++ unsigned u = 0; \ ++ assert(s); \ ++ for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \ ++ if (name##_table[i] && \ ++ streq(name##_table[i], s)) \ ++ return i; \ ++ if (safe_atou(s, &u) >= 0 && u < max) \ ++ return (type) u; \ ++ return (type) -1; \ ++ } \ ++ struct __useless_struct_to_allow_trailing_semicolon__ ++ + int fd_nonblock(int fd, bool nonblock); + int fd_cloexec(int fd, bool cloexec); + +@@ -473,25 +503,25 @@ int strdup_or_null(const char *a, char **b); + #define NULSTR_FOREACH_PAIR(i, j, l) \ + for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) + +-const char *ioprio_class_to_string(int i); ++int ioprio_class_to_string_alloc(int i, char **s); + int ioprio_class_from_string(const char *s); + + const char *sigchld_code_to_string(int i); + int sigchld_code_from_string(const char *s); + +-const char *log_facility_unshifted_to_string(int i); ++int log_facility_unshifted_to_string_alloc(int i, char **s); + int log_facility_unshifted_from_string(const char *s); + +-const char *log_level_to_string(int i); ++int log_level_to_string_alloc(int i, char **s); + int log_level_from_string(const char *s); + +-const char *sched_policy_to_string(int i); ++int sched_policy_to_string_alloc(int i, char **s); + int sched_policy_from_string(const char *s); + + const char *rlimit_to_string(int i); + int rlimit_from_string(const char *s); + +-const char *ip_tos_to_string(int i); ++int ip_tos_to_string_alloc(int i, char **s); + int ip_tos_from_string(const char *s); + + const char *signal_to_string(int i); diff --git a/0592-shared-max-in-the-string-number-conversion-is-meant-.patch b/0592-shared-max-in-the-string-number-conversion-is-meant-.patch new file mode 100644 index 0000000..db95c99 --- /dev/null +++ b/0592-shared-max-in-the-string-number-conversion-is-meant-.patch @@ -0,0 +1,24 @@ +From cda2707dc39059de1c459d3ef520a41b5b0fdce8 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 30 Oct 2012 15:45:50 +0100 +Subject: [PATCH] shared: "max" in the string->number conversion is meant to be + inclusive (cherry picked from commit + 8511dd1871fdea1ba0c63baa5becf0ede1658007) + +--- + src/shared/util.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/shared/util.h b/src/shared/util.h +index a3f6d9f..6125c21 100644 +--- a/src/shared/util.h ++++ b/src/shared/util.h +@@ -336,7 +336,7 @@ unsigned long long random_ull(void); + if (name##_table[i] && \ + streq(name##_table[i], s)) \ + return i; \ +- if (safe_atou(s, &u) >= 0 && u < max) \ ++ if (safe_atou(s, &u) >= 0 && u <= max) \ + return (type) u; \ + return (type) -1; \ + } \ diff --git a/0593-sd-journal-properly-parse-cursor-strings.patch b/0593-sd-journal-properly-parse-cursor-strings.patch new file mode 100644 index 0000000..fcf3c87 --- /dev/null +++ b/0593-sd-journal-properly-parse-cursor-strings.patch @@ -0,0 +1,56 @@ +From 4d8548297911835bd0cc1f57f066e50a21fa45c8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 27 Sep 2012 23:28:54 +0200 +Subject: [PATCH] sd-journal: properly parse cursor strings (cherry picked from + commit be3ea5eaf24f4507efe88b450f751da860a9d21c) + +--- + src/journal/sd-journal.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 5a82fbd..05b9484 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -816,35 +816,35 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { + + case 's': + seqnum_id_set = true; +- k = sd_id128_from_string(w+2, &seqnum_id); ++ k = sd_id128_from_string(item+2, &seqnum_id); + break; + + case 'i': + seqnum_set = true; +- if (sscanf(w+2, "%llx", &seqnum) != 1) ++ if (sscanf(item+2, "%llx", &seqnum) != 1) + k = -EINVAL; + break; + + case 'b': + boot_id_set = true; +- k = sd_id128_from_string(w+2, &boot_id); ++ k = sd_id128_from_string(item+2, &boot_id); + break; + + case 'm': + monotonic_set = true; +- if (sscanf(w+2, "%llx", &monotonic) != 1) ++ if (sscanf(item+2, "%llx", &monotonic) != 1) + k = -EINVAL; + break; + + case 't': + realtime_set = true; +- if (sscanf(w+2, "%llx", &realtime) != 1) ++ if (sscanf(item+2, "%llx", &realtime) != 1) + k = -EINVAL; + break; + + case 'x': + xor_hash_set = true; +- if (sscanf(w+2, "%llx", &xor_hash) != 1) ++ if (sscanf(item+2, "%llx", &xor_hash) != 1) + k = -EINVAL; + break; + } diff --git a/0594-journald-fix-bad-memory-access.patch b/0594-journald-fix-bad-memory-access.patch new file mode 100644 index 0000000..5b9ed09 --- /dev/null +++ b/0594-journald-fix-bad-memory-access.patch @@ -0,0 +1,25 @@ +From 234485c77fef18179cf88bd53a9d89eb514c477f Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Fri, 15 Feb 2013 10:09:08 +0100 +Subject: [PATCH] journald: fix bad memory access + +https://bugzilla.redhat.com/show_bug.cgi?id=875653 + +based on upstream commit 7d73c1343be02a59b17de0cd34375deeb815d89c +--- + src/journal/journald.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/journal/journald.c b/src/journal/journald.c +index 78e3278..1b4a98d 100644 +--- a/src/journal/journald.c ++++ b/src/journal/journald.c +@@ -357,7 +357,7 @@ static void server_rotate(Server *s) { + HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) { + r = journal_file_rotate(&f); + if (r < 0) +- if (f->path) ++ if (f) + log_error("Failed to rotate %s: %s", f->path, strerror(-r)); + else + log_error("Failed to create user journal: %s", strerror(-r)); diff --git a/systemd.spec b/systemd.spec index 2ec17ff..d921f7b 100644 --- a/systemd.spec +++ b/systemd.spec @@ -3,7 +3,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 44 -Release: 23%{?gitcommit:.git%{gitcommit}}%{?dist} +Release: 24%{?gitcommit:.git%{gitcommit}}%{?dist} License: GPLv2+ Group: System Environment/Base Summary: A System and Service Manager @@ -645,6 +645,15 @@ Patch0582: 0582-switch-root-remount-to-MS_PRIVATE.patch Patch0583: 0583-namespace-rework-namespace-support.patch Patch0584: 0584-nspawn-namespaces-make-sure-we-recursively-bind-moun.patch Patch0585: 0585-umount-MS_MGC_VAL-is-so-90s.patch +Patch0586: 0586-add-log_oom.patch +Patch0587: 0587-add-_cleanup_free_-_cleanup_close_.patch +Patch0588: 0588-mount-only-run-fsck-for-actual-device-nodes.patch +Patch0589: 0589-main-bump-up-RLIMIT_NOFILE-for-systemd-itself.patch +Patch0590: 0590-shared-libsystemd-daemon-check-for-empty-strings-in-.patch +Patch0591: 0591-shared-core-do-not-always-accept-numbers-in-string-l.patch +Patch0592: 0592-shared-max-in-the-string-number-conversion-is-meant-.patch +Patch0593: 0593-sd-journal-properly-parse-cursor-strings.patch +Patch0594: 0594-journald-fix-bad-memory-access.patch # For sysvinit tools Obsoletes: SysVinit < 2.86-24, sysvinit < 2.86-24 @@ -1033,6 +1042,10 @@ mv /etc/systemd/system/default.target.save /etc/systemd/system/default.target >/ %{_bindir}/systemd-analyze %changelog +* Fri Feb 15 2013 Michal Schmidt - 44-24 +- Selected fixes. +- Resolves: #891667, #876654, #902483, #875653 + * Wed Dec 19 2012 Michal Schmidt - 44-23 - Change mount propagation to shared by default. Should fix umounting of filesystems when PrivateTmp services are running.