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 +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 + + + z +- 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. ++ 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. + + + + + Z +- 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. ++ 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. + + + 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 +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 . ++***/ ++ ++/* 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 ++#include ++#include ++#include ++#include ++ ++#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 . ++***/ ++ ++#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 +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 +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 +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 +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 +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 @@ + + Kernel Command Line + +- When run as system instance systemd parses a few kernel command line arguments: ++ When run as system instance systemd parses a ++ number of kernel command line ++ argumentsIf 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 ++ /proc/cmdline ++ instead.: + + + 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 +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 - 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 - 37-17 - CVE-2012-1174 (#804118)