[systemd/f16] cherry-picks from v44
Michal Schmidt
michich at fedoraproject.org
Mon Mar 19 23:37:04 UTC 2012
commit 14c3102fc6ee3500b6f56ce8db7c35a96abcd60f
Author: Michal Schmidt <mschmidt at redhat.com>
Date: Tue Mar 20 00:34:19 2012 +0100
cherry-picks from v44
0162-man-reword-tmpfiles-selinux-bits.patch | 55 ++
0163-conf-enforce-UTF8-validty-everywhere.patch | 766 ++++++++++++++++++++
...dd-brute-force-fallback-for-close_all_fds.patch | 91 +++
...-warn-if-an-assignment-is-place-outside-o.patch | 31 +
0166-mount-fix-assertion.patch | 33 +
...-sure-that-the-name-for-per-connection-se.patch | 51 ++
...t-where-we-read-kernel-cmdline-options-fr.patch | 33 +
...t-etc-timezone-into-nspawn-environment-to.patch | 39 +
systemd.spec | 19 +-
9 files changed, 1117 insertions(+), 1 deletions(-)
---
diff --git a/0162-man-reword-tmpfiles-selinux-bits.patch b/0162-man-reword-tmpfiles-selinux-bits.patch
new file mode 100644
index 0000000..b8ba43b
--- /dev/null
+++ b/0162-man-reword-tmpfiles-selinux-bits.patch
@@ -0,0 +1,55 @@
+From e02e2cd119d731cdd830c9b4f5312ed35d2ad6ba Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 12 Mar 2012 21:51:39 +0100
+Subject: [PATCH] man: reword tmpfiles selinux bits (cherry picked from commit
+ 669e49fe2c841e53f7f2196bbe5d614013429ecd)
+
+---
+ man/tmpfiles.d.xml | 29 +++++++++++++++++------------
+ 1 files changed, 17 insertions(+), 12 deletions(-)
+
+diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
+index 4a8e831..74fcc75 100644
+--- a/man/tmpfiles.d.xml
++++ b/man/tmpfiles.d.xml
+@@ -158,23 +158,28 @@ d /run/user 0755 root root 10d</programlisting>
+
+ <varlistentry>
+ <term><varname>z</varname></term>
+- <listitem><para>Set ownership, access
+- mode and relabel security context of
+- a file or directory if it exists.
+- Lines of this type accept shell-style
+- globs in place of normal path names.
++ <listitem><para>Restore
++ SELinux security context label
++ and set ownership and access
++ mode of a file or directory if
++ it exists. Lines of this type
++ accept shell-style globs in
++ place of normal path names.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>Z</varname></term>
+- <listitem><para>Recursively set
+- ownership, access mode and relabel
+- security context of a path and
+- all its subdirectories (if it is a
+- directory). Lines of this type accept
+- shell-style globs in place of normal
+- path names.</para></listitem>
++ <listitem><para>Recursively
++ restore SELinux security
++ context label and set
++ ownership and access mode of a
++ path and all its
++ subdirectories (if it is a
++ directory). Lines of this type
++ accept shell-style globs in
++ place of normal path
++ names.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
diff --git a/0163-conf-enforce-UTF8-validty-everywhere.patch b/0163-conf-enforce-UTF8-validty-everywhere.patch
new file mode 100644
index 0000000..bc83e41
--- /dev/null
+++ b/0163-conf-enforce-UTF8-validty-everywhere.patch
@@ -0,0 +1,766 @@
+From d2ebd2444f5ecf11e091e8108232ef6b3322f32f Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 12 Mar 2012 22:22:16 +0100
+Subject: [PATCH] conf: enforce UTF8 validty everywhere
+
+we need to make sure that configuration data we expose via the bus ends
+up in using getting an assert(). Even though configuration data is only
+parsed from trusted sources we should be more careful with what we read.
+(cherry picked from commit 7f110ff9b8828b477e87de7b28c708cf69a3d008)
+
+Conflicts:
+
+ Makefile.am
+ TODO
+---
+ Makefile.am | 6 +-
+ src/conf-parser.c | 66 ++++++++++++----
+ src/load-fragment.c | 102 ++++++++++++++-----------
+ src/service.c | 13 +++-
+ src/utf8.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/utf8.h | 33 ++++++++
+ src/util.c | 17 +++--
+ 7 files changed, 382 insertions(+), 69 deletions(-)
+ create mode 100644 src/utf8.c
+ create mode 100644 src/utf8.h
+
+diff --git a/Makefile.am b/Makefile.am
+index 295944d..2f5dcdb 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -632,7 +632,8 @@ libsystemd_basic_la_SOURCES = \
+ src/socket-util.c \
+ src/log.c \
+ src/ratelimit.c \
+- src/exit-status.c
++ src/exit-status.c \
++ src/utf8.c
+
+ libsystemd_basic_la_CFLAGS = \
+ $(AM_CFLAGS) \
+@@ -757,7 +758,8 @@ EXTRA_DIST += \
+ src/logind-user.h \
+ src/logind-acl.h \
+ src/dbus-loop.h \
+- src/spawn-agent.h
++ src/spawn-agent.h \
++ src/utf8.h
+
+ MANPAGES = \
+ man/systemd.1 \
+diff --git a/src/conf-parser.c b/src/conf-parser.c
+index af34378..9edf637 100644
+--- a/src/conf-parser.c
++++ b/src/conf-parser.c
+@@ -30,6 +30,7 @@
+ #include "macro.h"
+ #include "strv.h"
+ #include "log.h"
++#include "utf8.h"
+
+ int config_item_table_lookup(
+ void *table,
+@@ -554,14 +555,23 @@ int config_parse_string(
+ assert(rvalue);
+ assert(data);
+
+- if (*rvalue) {
+- if (!(n = strdup(rvalue)))
+- return -ENOMEM;
+- } else
+- n = NULL;
++ n = cunescape(rvalue);
++ if (!n)
++ return -ENOMEM;
++
++ if (!utf8_is_valid(n)) {
++ log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
++ free(n);
++ return 0;
++ }
+
+ free(*s);
+- *s = n;
++ if (*n)
++ *s = n;
++ else {
++ free(n);
++ *s = NULL;
++ }
+
+ return 0;
+ }
+@@ -584,12 +594,18 @@ int config_parse_path(
+ assert(rvalue);
+ assert(data);
+
++ if (!utf8_is_valid(rvalue)) {
++ log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
++ return 0;
++ }
++
+ if (!path_is_absolute(rvalue)) {
+ log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+- if (!(n = strdup(rvalue)))
++ n = strdup(rvalue);
++ if (!n)
+ return -ENOMEM;
+
+ path_kill_slashes(n);
+@@ -616,6 +632,7 @@ int config_parse_strv(
+ unsigned k;
+ size_t l;
+ char *state;
++ int r;
+
+ assert(filename);
+ assert(lvalue);
+@@ -626,7 +643,8 @@ int config_parse_strv(
+ FOREACH_WORD_QUOTED(w, l, rvalue, state)
+ k++;
+
+- if (!(n = new(char*, k+1)))
++ n = new(char*, k+1);
++ if (!n)
+ return -ENOMEM;
+
+ if (*sv)
+@@ -635,9 +653,21 @@ int config_parse_strv(
+ else
+ k = 0;
+
+- FOREACH_WORD_QUOTED(w, l, rvalue, state)
+- if (!(n[k++] = cunescape_length(w, l)))
++ FOREACH_WORD_QUOTED(w, l, rvalue, state) {
++ n[k] = cunescape_length(w, l);
++ if (!n[k]) {
++ r = -ENOMEM;
+ goto fail;
++ }
++
++ if (!utf8_is_valid(n[k])) {
++ log_error("[%s:%u] String is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
++ free(n[k]);
++ continue;
++ }
++
++ k++;
++ }
+
+ n[k] = NULL;
+ free(*sv);
+@@ -650,7 +680,7 @@ fail:
+ free(n[k-1]);
+ free(n);
+
+- return -ENOMEM;
++ return r;
+ }
+
+ int config_parse_path_strv(
+@@ -680,7 +710,8 @@ int config_parse_path_strv(
+ FOREACH_WORD_QUOTED(w, l, rvalue, state)
+ k++;
+
+- if (!(n = new(char*, k+1)))
++ n = new(char*, k+1);
++ if (!n)
+ return -ENOMEM;
+
+ k = 0;
+@@ -689,11 +720,18 @@ int config_parse_path_strv(
+ n[k] = (*sv)[k];
+
+ FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+- if (!(n[k] = cunescape_length(w, l))) {
++ n[k] = strndup(w, l);
++ if (!n[k]) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
++ if (!utf8_is_valid(n[k])) {
++ log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
++ free(n[k]);
++ continue;
++ }
++
+ if (!path_is_absolute(n[k])) {
+ log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue);
+ free(n[k]);
+@@ -701,7 +739,6 @@ int config_parse_path_strv(
+ }
+
+ path_kill_slashes(n[k]);
+-
+ k++;
+ }
+
+@@ -712,7 +749,6 @@ int config_parse_path_strv(
+ return 0;
+
+ fail:
+- free(n[k]);
+ for (; k > 0; k--)
+ free(n[k-1]);
+ free(n);
+diff --git a/src/load-fragment.c b/src/load-fragment.c
+index ba28398..1d4a8c1 100644
+--- a/src/load-fragment.c
++++ b/src/load-fragment.c
+@@ -43,6 +43,7 @@
+ #include "missing.h"
+ #include "unit-name.h"
+ #include "bus-errors.h"
++#include "utf8.h"
+
+ #ifndef HAVE_SYSV_COMPAT
+ int config_parse_warn_compat(
+@@ -90,7 +91,6 @@ int config_parse_unit_deps(
+
+ k = unit_name_printf(u, t);
+ free(t);
+-
+ if (!k)
+ return -ENOMEM;
+
+@@ -128,22 +128,18 @@ int config_parse_unit_names(
+ char *t, *k;
+ int r;
+
+- if (!(t = strndup(w, l)))
++ t = strndup(w, l);
++ if (!t)
+ return -ENOMEM;
+
+ k = unit_name_printf(u, t);
+ free(t);
+-
+ if (!k)
+ return -ENOMEM;
+
+ r = unit_merge_by_name(u, k);
+-
+- if (r < 0) {
++ if (r < 0)
+ log_error("Failed to add name %s, ignoring: %s", k, strerror(-r));
+- free(k);
+- return 0;
+- }
+
+ free(k);
+ }
+@@ -162,27 +158,22 @@ int config_parse_unit_string_printf(
+ void *userdata) {
+
+ Unit *u = userdata;
+- char **s = data;
+ char *k;
++ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+- assert(s);
+ assert(u);
+
+- if (!(k = unit_full_printf(u, rvalue)))
++ k = unit_full_printf(u, rvalue);
++ if (!k)
+ return -ENOMEM;
+
+- free(*s);
+- if (*k)
+- *s = k;
+- else {
+- free(k);
+- *s = NULL;
+- }
++ r = config_parse_string(filename, line, section, lvalue, ltype, k, data, userdata);
++ free (k);
+
+- return 0;
++ return r;
+ }
+
+ int config_parse_unit_strv_printf(
+@@ -225,30 +216,22 @@ int config_parse_unit_path_printf(
+ void *userdata) {
+
+ Unit *u = userdata;
+- char **s = data;
+ char *k;
++ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+- assert(s);
+ assert(u);
+
+- if (!(k = unit_full_printf(u, rvalue)))
++ k = unit_full_printf(u, rvalue);
++ if (!k)
+ return -ENOMEM;
+
+- if (!path_is_absolute(k)) {
+- log_error("[%s:%u] Not an absolute path: %s", filename, line, k);
+- free(k);
+- return -EINVAL;
+- }
+-
+- path_kill_slashes(k);
+-
+- free(*s);
+- *s = k;
++ r = config_parse_path(filename, line, section, lvalue, ltype, k, data, userdata);
++ free(k);
+
+- return 0;
++ return r;
+ }
+
+ int config_parse_socket_listen(
+@@ -271,7 +254,8 @@ int config_parse_socket_listen(
+
+ s = (Socket*) data;
+
+- if (!(p = new0(SocketPort, 1)))
++ p = new0(SocketPort, 1);
++ if (!p)
+ return -ENOMEM;
+
+ if (streq(lvalue, "ListenFIFO")) {
+@@ -478,6 +462,7 @@ int config_parse_exec(
+ ExecCommand **e = data, *nce;
+ char *path, **n;
+ unsigned k;
++ int r;
+
+ assert(filename);
+ assert(lvalue);
+@@ -528,7 +513,8 @@ int config_parse_exec(
+ k++;
+ }
+
+- if (!(n = new(char*, k + !honour_argv0)))
++ n = new(char*, k + !honour_argv0);
++ if (!n)
+ return -ENOMEM;
+
+ k = 0;
+@@ -538,11 +524,33 @@ int config_parse_exec(
+
+ if (honour_argv0 && w == rvalue) {
+ assert(!path);
+- if (!(path = cunescape_length(w, l)))
++
++ path = strndup(w, l);
++ if (!path) {
++ r = -ENOMEM;
+ goto fail;
++ }
++
++ if (!utf8_is_valid(path)) {
++ log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
++ r = 0;
++ goto fail;
++ }
++
+ } else {
+- if (!(n[k++] = cunescape_length(w, l)))
++ char *c;
++
++ c = n[k++] = cunescape_length(w, l);
++ if (!c) {
++ r = -ENOMEM;
+ goto fail;
++ }
++
++ if (!utf8_is_valid(c)) {
++ log_error("[%s:%u] Path is not UTF-8 clean, ignoring assignment: %s", filename, line, rvalue);
++ r = 0;
++ goto fail;
++ }
+ }
+ }
+
+@@ -550,19 +558,25 @@ int config_parse_exec(
+
+ if (!n[0]) {
+ log_error("[%s:%u] Invalid command line, ignoring: %s", filename, line, rvalue);
+- strv_free(n);
+- free(path);
+- return 0;
++ r = 0;
++ goto fail;
+ }
+
+- if (!path)
+- if (!(path = strdup(n[0])))
++ if (!path) {
++ path = strdup(n[0]);
++ if (!path) {
++ r = -ENOMEM;
+ goto fail;
++ }
++ }
+
+ assert(path_is_absolute(path));
+
+- if (!(nce = new0(ExecCommand, 1)))
++ nce = new0(ExecCommand, 1);
++ if (!nce) {
++ r = -ENOMEM;
+ goto fail;
++ }
+
+ nce->argv = n;
+ nce->path = path;
+@@ -583,7 +597,7 @@ fail:
+ free(path);
+ free(nce);
+
+- return -ENOMEM;
++ return r;
+ }
+
+ DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
+diff --git a/src/service.c b/src/service.c
+index af83b6e..9005b02 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -37,6 +37,7 @@
+ #include "exit-status.h"
+ #include "def.h"
+ #include "util.h"
++#include "utf8.h"
+
+ #ifdef HAVE_SYSV_COMPAT
+
+@@ -3033,11 +3034,19 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
+ }
+
+ /* Interpret STATUS= */
+- if ((e = strv_find_prefix(tags, "STATUS="))) {
++ e = strv_find_prefix(tags, "STATUS=");
++ if (e) {
+ char *t;
+
+ if (e[7]) {
+- if (!(t = strdup(e+7))) {
++
++ if (!utf8_is_valid(e+7)) {
++ log_warning("Status message in notification is not UTF-8 clean.");
++ return;
++ }
++
++ t = strdup(e+7);
++ if (!t) {
+ log_error("Failed to allocate string.");
+ return;
+ }
+diff --git a/src/utf8.c b/src/utf8.c
+new file mode 100644
+index 0000000..11619dc
+--- /dev/null
++++ b/src/utf8.c
+@@ -0,0 +1,214 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++/***
++ This file is part of systemd.
++
++ Copyright 2012 Lennart Poettering
++
++ systemd is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ systemd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++/* This file is based on the GLIB utf8 validation functions. The
++ * original license text follows. */
++
++/* gutf8.c - Operations on UTF-8 strings.
++ *
++ * Copyright (C) 1999 Tom Tromey
++ * Copyright (C) 2000 Red Hat, Inc.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#include <errno.h>
++#include <stdlib.h>
++#include <inttypes.h>
++#include <string.h>
++#include <stdbool.h>
++
++#include "utf8.h"
++
++#define FILTER_CHAR '_'
++
++static inline bool is_unicode_valid(uint32_t ch) {
++
++ if (ch >= 0x110000) /* End of unicode space */
++ return false;
++ if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */
++ return false;
++ if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */
++ return false;
++ if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */
++ return false;
++
++ return true;
++}
++
++static inline bool is_continuation_char(uint8_t ch) {
++ if ((ch & 0xc0) != 0x80) /* 10xxxxxx */
++ return false;
++ return true;
++}
++
++static inline void merge_continuation_char(uint32_t *u_ch, uint8_t ch) {
++ *u_ch <<= 6;
++ *u_ch |= ch & 0x3f;
++}
++
++static char* utf8_validate(const char *str, char *output) {
++ uint32_t val = 0;
++ uint32_t min = 0;
++ const uint8_t *p, *last;
++ int size;
++ uint8_t *o;
++
++ assert(str);
++
++ o = (uint8_t*) output;
++ for (p = (const uint8_t*) str; *p; p++) {
++ if (*p < 128) {
++ if (o)
++ *o = *p;
++ } else {
++ last = p;
++
++ if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
++ size = 2;
++ min = 128;
++ val = (uint32_t) (*p & 0x1e);
++ goto ONE_REMAINING;
++ } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
++ size = 3;
++ min = (1 << 11);
++ val = (uint32_t) (*p & 0x0f);
++ goto TWO_REMAINING;
++ } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
++ size = 4;
++ min = (1 << 16);
++ val = (uint32_t) (*p & 0x07);
++ } else
++ goto error;
++
++ p++;
++ if (!is_continuation_char(*p))
++ goto error;
++ merge_continuation_char(&val, *p);
++
++ TWO_REMAINING:
++ p++;
++ if (!is_continuation_char(*p))
++ goto error;
++ merge_continuation_char(&val, *p);
++
++ ONE_REMAINING:
++ p++;
++ if (!is_continuation_char(*p))
++ goto error;
++ merge_continuation_char(&val, *p);
++
++ if (val < min)
++ goto error;
++
++ if (!is_unicode_valid(val))
++ goto error;
++
++ if (o) {
++ memcpy(o, last, (size_t) size);
++ o += size;
++ }
++
++ continue;
++
++ error:
++ if (o) {
++ *o = FILTER_CHAR;
++ p = last; /* We retry at the next character */
++ } else
++ goto failure;
++ }
++
++ if (o)
++ o++;
++ }
++
++ if (o) {
++ *o = '\0';
++ return output;
++ }
++
++ return (char*) str;
++
++failure:
++ return NULL;
++}
++
++char* utf8_is_valid (const char *str) {
++ return utf8_validate(str, NULL);
++}
++
++char* utf8_filter (const char *str) {
++ char *new_str;
++
++ assert(str);
++
++ new_str = malloc(strlen(str) + 1);
++ if (!new_str)
++ return NULL;
++
++ return utf8_validate(str, new_str);
++}
++
++char *ascii_is_valid(const char *str) {
++ const char *p;
++
++ assert(str);
++
++ for (p = str; *p; p++)
++ if ((unsigned char) *p >= 128)
++ return NULL;
++
++ return (char*) str;
++}
++
++char *ascii_filter(const char *str) {
++ char *r, *s, *d;
++ size_t l;
++
++ assert(str);
++
++ l = strlen(str);
++ r = malloc(l + 1);
++ if (!r)
++ return NULL;
++
++ for (s = r, d = r; *s; s++)
++ if ((unsigned char) *s < 128)
++ *(d++) = *s;
++
++ *d = 0;
++
++ return r;
++}
+diff --git a/src/utf8.h b/src/utf8.h
+new file mode 100644
+index 0000000..9a72bec
+--- /dev/null
++++ b/src/utf8.h
+@@ -0,0 +1,33 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++#ifndef fooutf8hfoo
++#define fooutf8hfoo
++
++/***
++ This file is part of systemd.
++
++ Copyright 2012 Lennart Poettering
++
++ systemd is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ systemd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#include "macro.h"
++
++char *utf8_is_valid(const char *s) _pure_;
++char *ascii_is_valid(const char *s) _pure_;
++
++char *utf8_filter(const char *s);
++char *ascii_filter(const char *s);
++
++#endif
+diff --git a/src/util.c b/src/util.c
+index 6a2c61f..0c9537e 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -1773,7 +1773,8 @@ char *cunescape_length(const char *s, size_t length) {
+
+ /* Undoes C style string escaping */
+
+- if (!(r = new(char, length+1)))
++ r = new(char, length+1);
++ if (!r)
+ return r;
+
+ for (f = s, t = r; f < s + length; f++) {
+@@ -1827,8 +1828,10 @@ char *cunescape_length(const char *s, size_t length) {
+ /* hexadecimal encoding */
+ int a, b;
+
+- if ((a = unhexchar(f[1])) < 0 ||
+- (b = unhexchar(f[2])) < 0) {
++ a = unhexchar(f[1]);
++ b = unhexchar(f[2]);
++
++ if (a < 0 || b < 0) {
+ /* Invalid escape code, let's take it literal then */
+ *(t++) = '\\';
+ *(t++) = 'x';
+@@ -1851,9 +1854,11 @@ char *cunescape_length(const char *s, size_t length) {
+ /* octal encoding */
+ int a, b, c;
+
+- if ((a = unoctchar(f[0])) < 0 ||
+- (b = unoctchar(f[1])) < 0 ||
+- (c = unoctchar(f[2])) < 0) {
++ a = unoctchar(f[0]);
++ b = unoctchar(f[1]);
++ c = unoctchar(f[2]);
++
++ if (a < 0 || b < 0 || c < 0) {
+ /* Invalid escape code, let's take it literal then */
+ *(t++) = '\\';
+ *(t++) = f[0];
diff --git a/0164-util-add-brute-force-fallback-for-close_all_fds.patch b/0164-util-add-brute-force-fallback-for-close_all_fds.patch
new file mode 100644
index 0000000..1254056
--- /dev/null
+++ b/0164-util-add-brute-force-fallback-for-close_all_fds.patch
@@ -0,0 +1,91 @@
+From 9697feabd63b19b4cbcebb8e6a369eb99e684a65 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 13 Mar 2012 02:29:27 +0100
+Subject: [PATCH] util: add brute-force fallback for close_all_fds()
+
+If /proc is not available (i.e. in chroot envs) let's fall back to brute
+forcing our way through the fd table.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=784921
+(cherry picked from commit b19be9eb9e231ccf350e0e051b687fc425c61904)
+---
+ src/util.c | 54 ++++++++++++++++++++++++++++++++++++++----------------
+ 1 files changed, 38 insertions(+), 16 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index 0c9537e..3a66c3b 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -2147,13 +2147,47 @@ int fd_cloexec(int fd, bool cloexec) {
+ return 0;
+ }
+
++static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
++ unsigned i;
++
++ assert(n_fdset == 0 || fdset);
++
++ for (i = 0; i < n_fdset; i++)
++ if (fdset[i] == fd)
++ return true;
++
++ return false;
++}
++
+ int close_all_fds(const int except[], unsigned n_except) {
+ DIR *d;
+ struct dirent *de;
+ int r = 0;
+
+- if (!(d = opendir("/proc/self/fd")))
+- return -errno;
++ assert(n_except == 0 || except);
++
++ d = opendir("/proc/self/fd");
++ if (!d) {
++ int fd;
++ struct rlimit rl;
++
++ /* When /proc isn't available (for example in chroots)
++ * the fallback is brute forcing through the fd
++ * table */
++
++ assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
++ for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
++
++ if (fd_in_set(fd, except, n_except))
++ continue;
++
++ if (close_nointr(fd) < 0)
++ if (errno != EBADF && r == 0)
++ r = -errno;
++ }
++
++ return r;
++ }
+
+ while ((de = readdir(d))) {
+ int fd = -1;
+@@ -2171,20 +2205,8 @@ int close_all_fds(const int except[], unsigned n_except) {
+ if (fd == dirfd(d))
+ continue;
+
+- if (except) {
+- bool found;
+- unsigned i;
+-
+- found = false;
+- for (i = 0; i < n_except; i++)
+- if (except[i] == fd) {
+- found = true;
+- break;
+- }
+-
+- if (found)
+- continue;
+- }
++ if (fd_in_set(fd, except, n_except))
++ continue;
+
+ if (close_nointr(fd) < 0) {
+ /* Valgrind has its own FD and doesn't want to have it closed */
diff --git a/0165-conf-parser-warn-if-an-assignment-is-place-outside-o.patch b/0165-conf-parser-warn-if-an-assignment-is-place-outside-o.patch
new file mode 100644
index 0000000..f0b56ec
--- /dev/null
+++ b/0165-conf-parser-warn-if-an-assignment-is-place-outside-o.patch
@@ -0,0 +1,31 @@
+From 0bf243e9c639dba0a80ce2ce50c8a7a97b7a8874 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 13 Mar 2012 02:41:29 +0100
+Subject: [PATCH] conf-parser: warn if an assignment is place outside of a
+ section
+
+https://bugzilla.redhat.com/show_bug.cgi?id=783134
+(cherry picked from commit 62f168a05b5a0b81a75a50791b80ae700dd00afb)
+---
+ src/conf-parser.c | 7 ++++++-
+ 1 files changed, 6 insertions(+), 1 deletions(-)
+
+diff --git a/src/conf-parser.c b/src/conf-parser.c
+index 9edf637..5561ae2 100644
+--- a/src/conf-parser.c
++++ b/src/conf-parser.c
+@@ -219,8 +219,13 @@ static int parse_line(
+ return 0;
+ }
+
+- if (sections && !*section)
++ if (sections && !*section) {
++
++ if (!relaxed)
++ log_info("[%s:%u] Assignment outside of section. Ignoring.", filename, line);
++
+ return 0;
++ }
+
+ e = strchr(l, '=');
+ if (!e) {
diff --git a/0166-mount-fix-assertion.patch b/0166-mount-fix-assertion.patch
new file mode 100644
index 0000000..75fee51
--- /dev/null
+++ b/0166-mount-fix-assertion.patch
@@ -0,0 +1,33 @@
+From a3e4e804ea93df6011a367a88190e2cb6174de9a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 13 Mar 2012 03:34:42 +0100
+Subject: [PATCH] mount: fix assertion
+
+https://bugzilla.redhat.com/show_bug.cgi?id=768523
+(cherry picked from commit 9631c090fd61070797f3a6139f873a3cabc5d28a)
+---
+ src/mount.c | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/mount.c b/src/mount.c
+index ccf1e9c..bac3ad3 100644
+--- a/src/mount.c
++++ b/src/mount.c
+@@ -189,7 +189,7 @@ static int mount_add_mount_links(Mount *m) {
+ if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
+ return r;
+
+- } else if (pm && path_startswith(pm->what, n->where)) {
++ } else if (pm && pm->what && path_startswith(pm->what, n->where)) {
+
+ if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
+ return r;
+@@ -197,7 +197,7 @@ static int mount_add_mount_links(Mount *m) {
+ if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
+ return r;
+
+- } else if (pn && path_startswith(pn->what, m->where)) {
++ } else if (pn && pn->what && path_startswith(pn->what, m->where)) {
+
+ if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
+ return r;
diff --git a/0167-socket-make-sure-that-the-name-for-per-connection-se.patch b/0167-socket-make-sure-that-the-name-for-per-connection-se.patch
new file mode 100644
index 0000000..62f670d
--- /dev/null
+++ b/0167-socket-make-sure-that-the-name-for-per-connection-se.patch
@@ -0,0 +1,51 @@
+From 2216ee3d049dda5d1a12fec5b862b101de355d43 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 14 Mar 2012 03:07:26 +0100
+Subject: [PATCH] socket: make sure that the name for per-connection services
+ are unique
+
+If a client connects to us repeatedly always using the same source port
+and we instantiate a service for the incoming connection this might
+clash with an old instance. Hence, include the connection number, the
+same way we do it for AF_UNIX to make connections unique.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=45297
+(cherry picked from commit 77b088c211a0939cb94969b487e5746bb05d12ae)
+---
+ src/socket.c | 9 ++++++---
+ 1 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/src/socket.c b/src/socket.c
+index b40b7a1..22e88b6 100644
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -560,7 +560,8 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
+ b = ntohl(remote.in.sin_addr.s_addr);
+
+ if (asprintf(&r,
+- "%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
++ "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
++ nr,
+ a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
+ ntohs(local.in.sin_port),
+ b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
+@@ -582,7 +583,8 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
+ *b = remote.in6.sin6_addr.s6_addr+12;
+
+ if (asprintf(&r,
+- "%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
++ "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
++ nr,
+ a[0], a[1], a[2], a[3],
+ ntohs(local.in6.sin6_port),
+ b[0], b[1], b[2], b[3],
+@@ -592,7 +594,8 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
+ char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
+
+ if (asprintf(&r,
+- "%s:%u-%s:%u",
++ "%u-%s:%u-%s:%u",
++ nr,
+ inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
+ ntohs(local.in6.sin6_port),
+ inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
diff --git a/0168-man-document-where-we-read-kernel-cmdline-options-fr.patch b/0168-man-document-where-we-read-kernel-cmdline-options-fr.patch
new file mode 100644
index 0000000..5961688
--- /dev/null
+++ b/0168-man-document-where-we-read-kernel-cmdline-options-fr.patch
@@ -0,0 +1,33 @@
+From c0aa995c459ff01a2299bc5dc9a303b923f978c8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 14 Mar 2012 14:13:12 +0100
+Subject: [PATCH] man: document where we read kernel cmdline options from
+ (cherry picked from commit
+ 45dc3a0478c61e83dedf26dc247fd3ddd2b20978)
+
+---
+ man/systemd.xml | 11 ++++++++++-
+ 1 files changed, 10 insertions(+), 1 deletions(-)
+
+diff --git a/man/systemd.xml b/man/systemd.xml
+index c1766e2..b1f57e3 100644
+--- a/man/systemd.xml
++++ b/man/systemd.xml
+@@ -948,7 +948,16 @@
+ <refsect1>
+ <title>Kernel Command Line</title>
+
+- <para>When run as system instance systemd parses a few kernel command line arguments:</para>
++ <para>When run as system instance systemd parses a
++ number of kernel command line
++ arguments<footnote><para>If run inside a Linux
++ container these arguments may be passed as command
++ line arguments to systemd itself, next to any of the
++ command line options listed in the Options section
++ above. If run outside of Linux containers, these
++ arguments are parsed from
++ <filename>/proc/cmdline</filename>
++ instead.</para></footnote>:</para>
+
+ <variablelist>
+ <varlistentry>
diff --git a/0169-nspawn-mount-etc-timezone-into-nspawn-environment-to.patch b/0169-nspawn-mount-etc-timezone-into-nspawn-environment-to.patch
new file mode 100644
index 0000000..caddd97
--- /dev/null
+++ b/0169-nspawn-mount-etc-timezone-into-nspawn-environment-to.patch
@@ -0,0 +1,39 @@
+From 5b283222a8834b3bfec59cac21c743d97e4a4a6d Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 15 Mar 2012 00:45:02 +0100
+Subject: [PATCH] nspawn: mount /etc/timezone into nspawn environment too
+ (cherry picked from commit
+ 4d1c38b8072dca18807371170d5e14fa8dc0baa5)
+
+---
+ src/nspawn.c | 10 +++++++++-
+ 1 files changed, 9 insertions(+), 1 deletions(-)
+
+diff --git a/src/nspawn.c b/src/nspawn.c
+index 52b4aa8..97efcd1 100644
+--- a/src/nspawn.c
++++ b/src/nspawn.c
+@@ -196,7 +196,7 @@ static int mount_all(const char *dest) {
+ }
+
+ /* Fix the timezone, if possible */
+- if (asprintf(&where, "%s/%s", dest, "/etc/localtime") >= 0) {
++ if (asprintf(&where, "%s/etc/localtime", dest) >= 0) {
+
+ if (mount("/etc/localtime", where, "bind", MS_BIND, NULL) >= 0)
+ mount("/etc/localtime", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+@@ -204,6 +204,14 @@ static int mount_all(const char *dest) {
+ free(where);
+ }
+
++ if (asprintf(&where, "%s/etc/timezone", dest) >= 0) {
++
++ if (mount("/etc/timezone", where, "bind", MS_BIND, NULL) >= 0)
++ mount("/etc/timezone", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
++
++ free(where);
++ }
++
+ return r;
+ }
+
diff --git a/systemd.spec b/systemd.spec
index bcc7915..d681e94 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -2,7 +2,7 @@ Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Version: 37
-Release: 17%{?dist}
+Release: 18%{?dist}
License: GPLv2+
Group: System Environment/Base
Summary: A System and Service Manager
@@ -214,6 +214,14 @@ Patch0158: 0158-nspawn-be-less-cryptic-when-clone-fails.patch
Patch0159: 0159-bash-completion-get-rid-of-awk-sed-and-grep.patch
Patch0160: 0160-mount-properly-check-return-for-mount_add_.patch
Patch0161: 0161-util-never-follow-symlinks-in-rm_rf_children.patch
+Patch0162: 0162-man-reword-tmpfiles-selinux-bits.patch
+Patch0163: 0163-conf-enforce-UTF8-validty-everywhere.patch
+Patch0164: 0164-util-add-brute-force-fallback-for-close_all_fds.patch
+Patch0165: 0165-conf-parser-warn-if-an-assignment-is-place-outside-o.patch
+Patch0166: 0166-mount-fix-assertion.patch
+Patch0167: 0167-socket-make-sure-that-the-name-for-per-connection-se.patch
+Patch0168: 0168-man-document-where-we-read-kernel-cmdline-options-fr.patch
+Patch0169: 0169-nspawn-mount-etc-timezone-into-nspawn-environment-to.patch
# For sysvinit tools
Obsoletes: SysVinit < 2.86-24, sysvinit < 2.86-24
@@ -535,6 +543,15 @@ fi
%{_bindir}/systemd-sysv-convert
%changelog
+* Tue Mar 20 2012 Michal Schmidt <mschmidt at redhat.com> - 37-18
+- enforce UTF8 validity of configuration data to avoid crashing in dbus
+- util: add brute-force fallback for close_all_fds() (#784921)
+- conf-parser: warn if an assignment is place outside of a section (#783134)
+- mount: fix assertion (#768523)
+- make sure that the name for per-connection services are unique (fdo#45297)
+- nspawn: mount /etc/timezone into nspawn environment too
+- minor documentation fixes
+
* Fri Mar 16 2012 Michal Schmidt <mschmidt at redhat.com> - 37-17
- CVE-2012-1174 (#804118)
More information about the scm-commits
mailing list