[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