[systemd/f17] Selected fixes.
Michal Schmidt
michich at fedoraproject.org
Fri Feb 15 09:24:05 UTC 2013
commit 0ae26f6d841adaec76776c2ee2a288f4a5104803
Author: Michal Schmidt <mschmidt at redhat.com>
Date: Fri Feb 15 09:56:58 2013 +0100
Selected fixes.
Resolves: #891667, #876654, #902483, #875653
0586-add-log_oom.patch | 52 +++
0587-add-_cleanup_free_-_cleanup_close_.patch | 56 +++
...unt-only-run-fsck-for-actual-device-nodes.patch | 36 ++
...-bump-up-RLIMIT_NOFILE-for-systemd-itself.patch | 105 +++++
...ystemd-daemon-check-for-empty-strings-in-.patch | 93 +++++
...-do-not-always-accept-numbers-in-string-l.patch | 405 ++++++++++++++++++++
...in-the-string-number-conversion-is-meant-.patch | 24 ++
...-sd-journal-properly-parse-cursor-strings.patch | 56 +++
0594-journald-fix-bad-memory-access.patch | 25 ++
systemd.spec | 15 +-
10 files changed, 866 insertions(+), 1 deletions(-)
---
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 <mschmidt at redhat.com>
+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 <mschmidt at redhat.com>
+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 <lennart at poettering.net>
+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 <lennart at poettering.net>
+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 <mschmidt at redhat.com>
+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 <mschmidt at redhat.com>
+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 <mschmidt at redhat.com>
+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 <lennart at poettering.net>
+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 <mschmidt at redhat.com>
+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 <mschmidt at redhat.com> - 44-24
+- Selected fixes.
+- Resolves: #891667, #876654, #902483, #875653
+
* Wed Dec 19 2012 Michal Schmidt <mschmidt at redhat.com> - 44-23
- Change mount propagation to shared by default. Should fix umounting of
filesystems when PrivateTmp services are running.
More information about the scm-commits
mailing list