diff -Nru systemd-229/debian/changelog systemd-229/debian/changelog --- systemd-229/debian/changelog 2018-11-08 00:01:30.000000000 +0000 +++ systemd-229/debian/changelog 2018-11-08 00:01:30.000000000 +0000 @@ -1,4 +1,4 @@ -systemd (229-4ubuntu21.7) xenial-security; urgency=medium +systemd (229-4ubuntu21.8) xenial-security; urgency=medium * SECURITY UPDATE: reexec state injection - debian/patches/CVE-2018-15686.patch: when deserializing state always use diff -Nru systemd-229/debian/patches/CVE-2018-6954.patch systemd-229/debian/patches/CVE-2018-6954.patch --- systemd-229/debian/patches/CVE-2018-6954.patch 2018-11-08 00:01:30.000000000 +0000 +++ systemd-229/debian/patches/CVE-2018-6954.patch 2018-11-08 00:01:30.000000000 +0000 @@ -41,7 +41,8 @@ assert(i); - assert(path); -- ++ assert(fd); + - /* We open the file with O_PATH here, to make the operation - * somewhat atomic. Also there's unfortunately no fchmodat() - * with AT_SYMLINK_NOFOLLOW, hence we emulate it here via @@ -50,8 +51,7 @@ - fd = open(path, O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH|O_NOATIME); - if (fd < 0) - return log_error_errno(errno, "Adjusting owner and mode for %s failed: %m", path); -+ assert(fd); - +- - if (fstatat(fd, "", &st, AT_EMPTY_PATH) < 0) - return log_error_errno(errno, "Failed to fstat() file %s: %m", path); + r = fd_get_path(fd, &path); @@ -421,8 +421,8 @@ + errno = 0; + de = readdir(d); + if (!de) { -+ if (errno > 0 && r == 0) { -+ r = -errno; ++ if (errno > 0) { ++ q = -errno; + goto finish; + } @@ -467,7 +467,7 @@ _cleanup_globfree_ glob_t g = { .gl_closedir = (void (*)(void *)) closedir, .gl_readdir = (struct dirent *(*)(void *)) readdir, -@@ -1120,12 +1202,48 @@ +@@ -1120,12 +1202,53 @@ k = action(i, *fn); if (k < 0 && r == 0) r = k; @@ -475,26 +475,31 @@ + + return r; +} - -- if (recursive) { -- k = item_do_children(i, *fn, action); -- if (k < 0 && r == 0) -- r = k; ++ +static int glob_item_recursively(Item *i, fdaction_t action) { + _cleanup_globfree_ glob_t g = { ++ .gl_closedir = (void (*)(void *)) closedir, ++ .gl_readdir = (struct dirent *(*)(void *)) readdir, + .gl_opendir = (void *(*)(const char *)) opendir_nomod, ++ .gl_lstat = lstat, ++ .gl_stat = stat, + }; + int r = 0, k; + char **fn; + -+ k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g); -+ if (k < 0 && k != -ENOENT) -+ return log_error_errno(k, "glob(%s) failed: %m", i->path); ++ errno = 0; ++ k = glob(i->path, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g); ++ if (k != 0 && k != GLOB_NOMATCH) ++ return log_error_errno(errno ?: EIO, "glob(%s) failed: %m", i->path); + + STRV_FOREACH(fn, g.gl_pathv) { + _cleanup_close_ int fd = -1; + struct stat st; -+ + +- if (recursive) { +- k = item_do_children(i, *fn, action); +- if (k < 0 && r == 0) +- r = k; + /* Make sure we won't trigger/follow file object (such as + * device nodes, automounts, ...) pointed out by 'fn' with + * O_PATH. Note, when O_PATH is used, flags other than @@ -520,7 +525,7 @@ } return r; -@@ -1209,7 +1327,7 @@ +@@ -1209,7 +1332,7 @@ break; case WRITE_FILE: @@ -529,7 +534,7 @@ if (r < 0) return r; -@@ -1455,49 +1573,49 @@ +@@ -1455,49 +1578,49 @@ case ADJUST_MODE: case RELABEL_PATH: @@ -587,7 +592,7 @@ if (r < 0) return r; break; -@@ -1574,7 +1692,7 @@ +@@ -1574,7 +1697,7 @@ case REMOVE_PATH: case TRUNCATE_DIRECTORY: case RECURSIVE_REMOVE_PATH: @@ -596,7 +601,7 @@ break; } -@@ -1650,7 +1768,7 @@ +@@ -1650,7 +1773,7 @@ clean_item_instance(i, i->path); break; case IGNORE_DIRECTORY_PATH: @@ -650,131 +655,6 @@ /* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */ #define ERRNO_IS_DISCONNECT(r) \ IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH) ---- a/src/basic/glob-util.c -+++ b/src/basic/glob-util.c -@@ -17,13 +17,48 @@ - along with systemd; If not, see . - ***/ - -+#include - #include - #include -+#include - -+#include "dirent-util.h" - #include "glob-util.h" - #include "macro.h" - #include "strv.h" - -+int safe_glob(const char *path, int flags, glob_t *pglob) { -+ int k; -+ -+ /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */ -+ assert(!(flags & GLOB_ALTDIRFUNC)); -+ -+ if (!pglob->gl_closedir) -+ pglob->gl_closedir = (void (*)(void *)) closedir; -+ if (!pglob->gl_readdir) -+ pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot; -+ if (!pglob->gl_opendir) -+ pglob->gl_opendir = (void *(*)(const char *)) opendir; -+ if (!pglob->gl_lstat) -+ pglob->gl_lstat = lstat; -+ if (!pglob->gl_stat) -+ pglob->gl_stat = stat; -+ -+ errno = 0; -+ k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob); -+ -+ if (k == GLOB_NOMATCH) -+ return -ENOENT; -+ if (k == GLOB_NOSPACE) -+ return -ENOMEM; -+ if (k != 0) -+ return errno > 0 ? -errno : -EIO; -+ if (strv_isempty(pglob->gl_pathv)) -+ return -ENOENT; -+ -+ return 0; -+} -+ - int glob_exists(const char *path) { - _cleanup_globfree_ glob_t g = {}; - int k; ---- a/src/basic/glob-util.h -+++ b/src/basic/glob-util.h -@@ -19,12 +19,16 @@ - along with systemd; If not, see . - ***/ - -+#include - #include - #include - - #include "macro.h" - #include "string-util.h" - -+/* Note: this function modifies pglob to set various functions. */ -+int safe_glob(const char *path, int flags, glob_t *pglob); -+ - int glob_exists(const char *path); - int glob_extend(char ***strv, const char *path); - ---- a/src/basic/dirent-util.c -+++ b/src/basic/dirent-util.c -@@ -76,3 +76,14 @@ - - return endswith(de->d_name, suffix); - } -+ -+struct dirent* readdir_no_dot(DIR *dirp) { -+ struct dirent* d; -+ -+ for (;;) { -+ d = readdir(dirp); -+ if (d && dot_or_dot_dot(d->d_name)) -+ continue; -+ return d; -+ } -+} ---- a/src/basic/dirent-util.h -+++ b/src/basic/dirent-util.h -@@ -31,6 +31,8 @@ - bool dirent_is_file(const struct dirent *de) _pure_; - bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_; - -+struct dirent* readdir_no_dot(DIR *dirp); -+ - #define FOREACH_DIRENT(de, d, on_error) \ - for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ - if (!de) { \ ---- a/src/basic/path-util.c -+++ b/src/basic/path-util.c -@@ -798,3 +798,16 @@ - path_startswith(path, "/dev/") || - path_startswith(path, "/sys/"); - } -+ -+bool dot_or_dot_dot(const char *path) { -+ if (!path) -+ return false; -+ if (path[0] != '.') -+ return false; -+ if (path[1] == 0) -+ return true; -+ if (path[1] != '.') -+ return false; -+ -+ return path[2] == 0; -+} ---- a/src/basic/path-util.h -+++ b/src/basic/path-util.h -@@ -109,3 +109,5 @@ - bool hidden_file(const char *filename) _pure_; - - bool is_device_path(const char *path); -+ -+bool dot_or_dot_dot(const char *path); --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -134,6 +134,14 @@