aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/systemd/systemd/0001-tmpfiles-don-t-resolve-pathnames-when-traversing-rec.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/systemd/systemd/0001-tmpfiles-don-t-resolve-pathnames-when-traversing-rec.patch')
-rw-r--r--meta/recipes-core/systemd/systemd/0001-tmpfiles-don-t-resolve-pathnames-when-traversing-rec.patch643
1 files changed, 643 insertions, 0 deletions
diff --git a/meta/recipes-core/systemd/systemd/0001-tmpfiles-don-t-resolve-pathnames-when-traversing-rec.patch b/meta/recipes-core/systemd/systemd/0001-tmpfiles-don-t-resolve-pathnames-when-traversing-rec.patch
new file mode 100644
index 0000000000..108e4ad8b8
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/0001-tmpfiles-don-t-resolve-pathnames-when-traversing-rec.patch
@@ -0,0 +1,643 @@
+From 33dc9a280f952f503e5493ee29f6815bef29d551 Mon Sep 17 00:00:00 2001
+From: Franck Bui <fbui@suse.com>
+Date: Fri, 2 Mar 2018 17:19:32 +0100
+Subject: [PATCH] tmpfiles: don't resolve pathnames when traversing recursively
+ through directory trees
+
+Otherwise we can be fooled if one path component is replaced underneath us.
+
+The patch achieves that by always operating at file descriptor level (by using
+*at() helpers) and by making sure we do not any path resolution when traversing
+direcotry trees.
+
+However this is not always possible, for instance when listing the content of a
+directory or some operations don't provide the *at() helpers or others (such as
+fchmodat()) don't have the AT_EMPTY_PATH flag. In such cases we operate on
+/proc/self/fd/%i pseudo-symlink instead, which works the same for all kinds of
+objects and requires no checking of type beforehand.
+
+Also O_PATH flag is used when opening file objects in order to prevent
+undesired behaviors: device nodes from reacting, automounts from
+triggering, etc...
+
+Fixes: CVE-2018-6954
+
+Origin: upstream, https://github.com/systemd/systemd/commit/936f6bdb803c432578e2cdcc5f93f3bfff93aff0
+Bug: https://github.com/systemd/systemd/issues/7986
+
+Patch from:
+systemd_237-3ubuntu10.13.debian CVE-2018-6954.patch
+
+https://usn.ubuntu.com/3816-1/ states that CVE-2018-6954 doesn't
+affect Ubuntu 18.10 which uses the same version of systemd as thud
+(239).
+
+CVE: CVE-2018-6954
+Upstream-Status: Backport
+
+Signed-off-by: George McCollister <george.mccollister@gmail.com>
+---
+ src/tmpfiles/tmpfiles.c | 363 +++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 239 insertions(+), 124 deletions(-)
+
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index 88cc543f09..613d418eb3 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -792,94 +792,105 @@ static bool hardlink_vulnerable(struct stat *st) {
+ return !S_ISDIR(st->st_mode) && st->st_nlink > 1 && dangerous_hardlinks();
+ }
+
+-static int path_set_perms(Item *i, const char *path) {
+- char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+- _cleanup_close_ int fd = -1;
+- struct stat st;
++static int fd_set_perms(Item *i, int fd, const struct stat *st) {
++ _cleanup_free_ char *path = NULL;
++ int r;
+
+ assert(i);
+- assert(path);
+-
+- if (!i->mode_set && !i->uid_set && !i->gid_set)
+- goto shortcut;
+-
+- /* 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
+- * O_PATH. */
+-
+- fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
+- if (fd < 0) {
+- int level = LOG_ERR, r = -errno;
++ assert(fd);
+
+- /* Option "e" operates only on existing objects. Do not
+- * print errors about non-existent files or directories */
+- if (i->type == EMPTY_DIRECTORY && errno == ENOENT) {
+- level = LOG_DEBUG;
+- r = 0;
+- }
+-
+- log_full_errno(level, errno, "Adjusting owner and mode for %s failed: %m", path);
++ r = fd_get_path(fd, &path);
++ if (r < 0)
+ return r;
+- }
+
+- if (fstatat(fd, "", &st, AT_EMPTY_PATH) < 0)
+- return log_error_errno(errno, "Failed to fstat() file %s: %m", path);
++ if (!i->mode_set && !i->uid_set && !i->gid_set)
++ goto shortcut;
+
+- if (hardlink_vulnerable(&st)) {
++ if (hardlink_vulnerable(st)) {
+ log_error("Refusing to set permissions on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.", path);
+ return -EPERM;
+ }
+
+- xsprintf(fn, "/proc/self/fd/%i", fd);
+-
+ if (i->mode_set) {
+- if (S_ISLNK(st.st_mode))
++ if (S_ISLNK(st->st_mode))
+ log_debug("Skipping mode fix for symlink %s.", path);
+ else {
+ mode_t m = i->mode;
+
+ if (i->mask_perms) {
+- if (!(st.st_mode & 0111))
++ if (!(st->st_mode & 0111))
+ m &= ~0111;
+- if (!(st.st_mode & 0222))
++ if (!(st->st_mode & 0222))
+ m &= ~0222;
+- if (!(st.st_mode & 0444))
++ if (!(st->st_mode & 0444))
+ m &= ~0444;
+- if (!S_ISDIR(st.st_mode))
++ if (!S_ISDIR(st->st_mode))
+ m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */
+ }
+
+- if (m == (st.st_mode & 07777))
+- log_debug("\"%s\" has correct mode %o already.", path, st.st_mode);
++ if (m == (st->st_mode & 07777))
++ log_debug("\"%s\" has correct mode %o already.", path, st->st_mode);
+ else {
++ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
++
+ log_debug("Changing \"%s\" to mode %o.", path, m);
+
+- if (chmod(fn, m) < 0)
+- return log_error_errno(errno, "chmod() of %s via %s failed: %m", path, fn);
++ /* fchmodat() still doesn't have AT_EMPTY_PATH flag. */
++ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
++
++ if (chmod(procfs_path, m) < 0)
++ return log_error_errno(errno, "chmod() of %s via %s failed: %m", path, procfs_path);
+ }
+ }
+ }
+
+- if ((i->uid_set && i->uid != st.st_uid) ||
+- (i->gid_set && i->gid != st.st_gid)) {
++ if ((i->uid_set && i->uid != st->st_uid) ||
++ (i->gid_set && i->gid != st->st_gid)) {
+ log_debug("Changing \"%s\" to owner "UID_FMT":"GID_FMT,
+ path,
+ i->uid_set ? i->uid : UID_INVALID,
+ i->gid_set ? i->gid : GID_INVALID);
+
+- if (chown(fn,
+- i->uid_set ? i->uid : UID_INVALID,
+- i->gid_set ? i->gid : GID_INVALID) < 0)
+- return log_error_errno(errno, "chown() of %s via %s failed: %m", path, fn);
++ if (fchownat(fd,
++ "",
++ i->uid_set ? i->uid : UID_INVALID,
++ i->gid_set ? i->gid : GID_INVALID,
++ AT_EMPTY_PATH) < 0)
++ return log_error_errno(errno, "fchownat() of %s failed: %m", path);
+ }
+
+- fd = safe_close(fd);
+-
+ shortcut:
+ return label_fix(path, false, false);
+ }
+
++static int path_set_perms(Item *i, const char *path) {
++ _cleanup_close_ int fd = -1;
++ struct stat st;
++
++ assert(i);
++ assert(path);
++
++ fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
++ if (fd < 0) {
++ int level = LOG_ERR, r = -errno;
++
++ /* Option "e" operates only on existing objects. Do not
++ * print errors about non-existent files or directories */
++ if (i->type == EMPTY_DIRECTORY && errno == ENOENT) {
++ level = LOG_DEBUG;
++ r = 0;
++ }
++
++ log_full_errno(level, errno, "Adjusting owner and mode for %s failed: %m", path);
++ return r;
++ }
++
++ if (fstat(fd, &st) < 0)
++ return log_error_errno(errno, "Failed to fstat() file %s: %m", path);
++
++ return fd_set_perms(i, fd, &st);
++}
++
+ static int parse_xattrs_from_arg(Item *i) {
+ const char *p;
+ int r;
+@@ -918,21 +929,43 @@ static int parse_xattrs_from_arg(Item *i) {
+ return 0;
+ }
+
+-static int path_set_xattrs(Item *i, const char *path) {
++static int fd_set_xattrs(Item *i, int fd, const struct stat *st) {
++ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
++ _cleanup_free_ char *path = NULL;
+ char **name, **value;
++ int r;
+
+ assert(i);
+- assert(path);
++ assert(fd);
++
++ r = fd_get_path(fd, &path);
++ if (r < 0)
++ return r;
++
++ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+
+ STRV_FOREACH_PAIR(name, value, i->xattrs) {
+ log_debug("Setting extended attribute '%s=%s' on %s.", *name, *value, path);
+- if (lsetxattr(path, *name, *value, strlen(*value), 0) < 0)
++ if (setxattr(procfs_path, *name, *value, strlen(*value), 0) < 0)
+ return log_error_errno(errno, "Setting extended attribute %s=%s on %s failed: %m",
+ *name, *value, path);
+ }
+ return 0;
+ }
+
++static int path_set_xattrs(Item *i, const char *path) {
++ _cleanup_close_ int fd = -1;
++
++ assert(i);
++ assert(path);
++
++ fd = open(path, O_CLOEXEC|O_NOFOLLOW|O_PATH);
++ if (fd < 0)
++ return log_error_errno(errno, "Cannot open '%s': %m", path);
++
++ return fd_set_xattrs(i, fd, NULL);
++}
++
+ static int parse_acls_from_arg(Item *item) {
+ #if HAVE_ACL
+ int r;
+@@ -998,52 +1031,71 @@ static int path_set_acl(const char *path, const char *pretty, acl_type_t type, a
+ }
+ #endif
+
+-static int path_set_acls(Item *item, const char *path) {
++static int fd_set_acls(Item *item, int fd, const struct stat *st) {
+ int r = 0;
+ #if HAVE_ACL
+- char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+- _cleanup_close_ int fd = -1;
+- struct stat st;
++ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
++ _cleanup_free_ char *path = NULL;
+
+ assert(item);
+- assert(path);
+-
+- fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
+- if (fd < 0)
+- return log_error_errno(errno, "Adjusting ACL of %s failed: %m", path);
++ assert(fd);
++ assert(st);
+
+- 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);
++ if (r < 0)
++ return r;
+
+- if (hardlink_vulnerable(&st)) {
++ if (hardlink_vulnerable(st)) {
+ log_error("Refusing to set ACLs on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.", path);
+ return -EPERM;
+ }
+
+- if (S_ISLNK(st.st_mode)) {
++ if (S_ISLNK(st->st_mode)) {
+ log_debug("Skipping ACL fix for symlink %s.", path);
+ return 0;
+ }
+
+- xsprintf(fn, "/proc/self/fd/%i", fd);
++ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+
+ if (item->acl_access)
+- r = path_set_acl(fn, path, ACL_TYPE_ACCESS, item->acl_access, item->force);
++ r = path_set_acl(procfs_path, path, ACL_TYPE_ACCESS, item->acl_access, item->force);
+
+ if (r == 0 && item->acl_default)
+- r = path_set_acl(fn, path, ACL_TYPE_DEFAULT, item->acl_default, item->force);
++ r = path_set_acl(procfs_path, path, ACL_TYPE_DEFAULT, item->acl_default, item->force);
+
+ if (r > 0)
+ return -r; /* already warned */
+- else if (r == -EOPNOTSUPP) {
++ if (r == -EOPNOTSUPP) {
+ log_debug_errno(r, "ACLs not supported by file system at %s", path);
+ return 0;
+- } else if (r < 0)
+- log_error_errno(r, "ACL operation on \"%s\" failed: %m", path);
++ }
++ if (r < 0)
++ return log_error_errno(r, "ACL operation on \"%s\" failed: %m", path);
+ #endif
+ return r;
+ }
+
++static int path_set_acls(Item *item, const char *path) {
++ int r = 0;
++#ifdef HAVE_ACL
++ _cleanup_close_ int fd = -1;
++ struct stat st;
++
++ assert(item);
++ assert(path);
++
++ fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
++ if (fd < 0)
++ return log_error_errno(errno, "Adjusting ACL of %s failed: %m", path);
++
++ if (fstat(fd, &st) < 0)
++ return log_error_errno(errno, "Failed to fstat() file %s: %m", path);
++
++ r = fd_set_acls(item, fd, &st);
++ #endif
++ return r;
++ }
++
+ #define ATTRIBUTES_ALL \
+ (FS_NOATIME_FL | \
+ FS_SYNC_FL | \
+@@ -1143,30 +1195,24 @@ static int parse_attribute_from_arg(Item *item) {
+ return 0;
+ }
+
+-static int path_set_attribute(Item *item, const char *path) {
+- _cleanup_close_ int fd = -1;
+- struct stat st;
++static int fd_set_attribute(Item *item, int fd, const struct stat *st) {
++ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
++ _cleanup_close_ int procfs_fd = -1;
++ _cleanup_free_ char *path = NULL;
+ unsigned f;
+ int r;
+
+ if (!item->attribute_set || item->attribute_mask == 0)
+ return 0;
+
+- fd = open(path, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOATIME|O_NOFOLLOW);
+- if (fd < 0) {
+- if (errno == ELOOP)
+- return log_error_errno(errno, "Skipping file attributes adjustment on symlink %s.", path);
+-
+- return log_error_errno(errno, "Cannot open '%s': %m", path);
+- }
+-
+- if (fstat(fd, &st) < 0)
+- return log_error_errno(errno, "Cannot stat '%s': %m", path);
++ r = fd_get_path(fd, &path);
++ if (r < 0)
++ return r;
+
+ /* Issuing the file attribute ioctls on device nodes is not
+ * safe, as that will be delivered to the drivers, not the
+ * file system containing the device node. */
+- if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
++ if (!S_ISREG(st->st_mode) && !S_ISDIR(st->st_mode)) {
+ log_error("Setting file flags is only supported on regular files and directories, cannot set on '%s'.", path);
+ return -EINVAL;
+ }
+@@ -1174,10 +1220,16 @@ static int path_set_attribute(Item *item, const char *path) {
+ f = item->attribute_value & item->attribute_mask;
+
+ /* Mask away directory-specific flags */
+- if (!S_ISDIR(st.st_mode))
++ if (!S_ISDIR(st->st_mode))
+ f &= ~FS_DIRSYNC_FL;
+
+- r = chattr_fd(fd, f, item->attribute_mask);
++ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
++
++ procfs_fd = open(procfs_path, O_RDONLY|O_CLOEXEC|O_NOATIME);
++ if (procfs_fd < 0)
++ return -errno;
++
++ r = chattr_fd(procfs_fd, f, item->attribute_mask);
+ if (r < 0)
+ log_full_errno(IN_SET(r, -ENOTTY, -EOPNOTSUPP) ? LOG_DEBUG : LOG_WARNING,
+ r,
+@@ -1187,6 +1239,23 @@ static int path_set_attribute(Item *item, const char *path) {
+ return 0;
+ }
+
++static int path_set_attribute(Item *item, const char *path) {
++ _cleanup_close_ int fd = -1;
++ struct stat st;
++
++ if (!item->attribute_set || item->attribute_mask == 0)
++ return 0;
++
++ fd = open(path, O_CLOEXEC|O_NOFOLLOW|O_PATH);
++ if (fd < 0)
++ return log_error_errno(errno, "Cannot open '%s': %m", path);
++
++ if (fstat(fd, &st) < 0)
++ return log_error_errno(errno, "Cannot stat '%s': %m", path);
++
++ return fd_set_attribute(item, fd, &st);
++}
++
+ static int write_one_file(Item *i, const char *path) {
+ _cleanup_close_ int fd = -1;
+ int flags, r = 0;
+@@ -1251,48 +1320,58 @@ done:
+ }
+
+ typedef int (*action_t)(Item *, const char *);
++typedef int (*fdaction_t)(Item *, int fd, const struct stat *st);
+
+-static int item_do_children(Item *i, const char *path, action_t action) {
+- _cleanup_closedir_ DIR *d;
+- struct dirent *de;
+- int r = 0;
++static int item_do(Item *i, int fd, const struct stat *st, fdaction_t action) {
++ int r = 0, q;
+
+ assert(i);
+- assert(path);
++ assert(fd >= 0);
++ assert(st);
+
+ /* This returns the first error we run into, but nevertheless
+ * tries to go on */
++ r = action(i, fd, st);
+
+- d = opendir_nomod(path);
+- if (!d)
+- return IN_SET(errno, ENOENT, ENOTDIR, ELOOP) ? 0 : -errno;
++ if (S_ISDIR(st->st_mode)) {
++ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
++ _cleanup_closedir_ DIR *d = NULL;
++ struct dirent *de;
+
+- FOREACH_DIRENT_ALL(de, d, r = -errno) {
+- _cleanup_free_ char *p = NULL;
+- int q;
++ /* The passed 'fd' was opened with O_PATH. We need to convert
++ * it into a 'regular' fd before reading the directory content. */
++ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+
+- if (dot_or_dot_dot(de->d_name))
+- continue;
++ d = opendir(procfs_path);
++ if (!d) {
++ r = r ?: -errno;
++ goto finish;
++ }
+
+- p = strjoin(path, "/", de->d_name);
+- if (!p)
+- return -ENOMEM;
++ FOREACH_DIRENT_ALL(de, d, q = -errno; goto finish) {
++ struct stat de_st;
++ int de_fd;
++
++ if (dot_or_dot_dot(de->d_name))
++ continue;
+
+- q = action(i, p);
+- if (q < 0 && q != -ENOENT && r == 0)
+- r = q;
++ de_fd = openat(fd, de->d_name, O_NOFOLLOW|O_CLOEXEC|O_PATH);
++ if (de_fd >= 0 && fstat(de_fd, &de_st) >= 0)
++ /* pass ownership of dirent fd over */
++ q = item_do(i, de_fd, &de_st, action);
++ else
++ q = -errno;
+
+- if (IN_SET(de->d_type, DT_UNKNOWN, DT_DIR)) {
+- q = item_do_children(i, p, action);
+ if (q < 0 && r == 0)
+ r = q;
+ }
+ }
+-
++finish:
++ safe_close(fd);
+ return r;
+ }
+
+-static int glob_item(Item *i, action_t action, bool recursive) {
++static int glob_item(Item *i, action_t action) {
+ _cleanup_globfree_ glob_t g = {
+ #ifdef GLOB_ALTDIRFUNC
+ .gl_opendir = (void *(*)(const char *)) opendir_nomod,
+@@ -1309,12 +1388,48 @@ static int glob_item(Item *i, action_t action, bool recursive) {
+ k = action(i, *fn);
+ if (k < 0 && r == 0)
+ r = k;
++ }
+
+- if (recursive) {
+- k = item_do_children(i, *fn, action);
+- if (k < 0 && r == 0)
+- r = k;
++ return r;
++}
++
++static int glob_item_recursively(Item *i, fdaction_t action) {
++ _cleanup_globfree_ glob_t g = {
++ .gl_opendir = (void *(*)(const char *)) opendir_nomod,
++ };
++ 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);
++
++ STRV_FOREACH(fn, g.gl_pathv) {
++ _cleanup_close_ int fd = -1;
++ struct stat st;
++
++ /* 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
++ * O_CLOEXEC, O_DIRECTORY, and O_NOFOLLOW are ignored. */
++
++ fd = open(*fn, O_CLOEXEC|O_NOFOLLOW|O_PATH);
++ if (fd < 0) {
++ r = r ?: -errno;
++ continue;
++ }
++
++ if (fstat(fd, &st) < 0) {
++ r = r ?: -errno;
++ continue;
+ }
++
++ k = item_do(i, fd, &st, action);
++ if (k < 0 && r == 0)
++ r = k;
++
++ /* we passed fd ownership to the previous call */
++ fd = -1;
+ }
+
+ return r;
+@@ -1403,7 +1518,7 @@ static int create_item(Item *i) {
+ break;
+
+ case WRITE_FILE:
+- r = glob_item(i, write_one_file, false);
++ r = glob_item(i, write_one_file);
+ if (r < 0)
+ return r;
+
+@@ -1662,49 +1777,49 @@ static int create_item(Item *i) {
+
+ case ADJUST_MODE:
+ case RELABEL_PATH:
+- r = glob_item(i, path_set_perms, false);
++ r = glob_item(i, path_set_perms);
+ if (r < 0)
+ return r;
+ break;
+
+ case RECURSIVE_RELABEL_PATH:
+- r = glob_item(i, path_set_perms, true);
++ r = glob_item_recursively(i, fd_set_perms);
+ if (r < 0)
+ return r;
+ break;
+
+ case SET_XATTR:
+- r = glob_item(i, path_set_xattrs, false);
++ r = glob_item(i, path_set_xattrs);
+ if (r < 0)
+ return r;
+ break;
+
+ case RECURSIVE_SET_XATTR:
+- r = glob_item(i, path_set_xattrs, true);
++ r = glob_item_recursively(i, fd_set_xattrs);
+ if (r < 0)
+ return r;
+ break;
+
+ case SET_ACL:
+- r = glob_item(i, path_set_acls, false);
++ r = glob_item(i, path_set_acls);
+ if (r < 0)
+ return r;
+ break;
+
+ case RECURSIVE_SET_ACL:
+- r = glob_item(i, path_set_acls, true);
++ r = glob_item_recursively(i, fd_set_acls);
+ if (r < 0)
+ return r;
+ break;
+
+ case SET_ATTRIBUTE:
+- r = glob_item(i, path_set_attribute, false);
++ r = glob_item(i, path_set_attribute);
+ if (r < 0)
+ return r;
+ break;
+
+ case RECURSIVE_SET_ATTRIBUTE:
+- r = glob_item(i, path_set_attribute, true);
++ r = glob_item_recursively(i, fd_set_attribute);
+ if (r < 0)
+ return r;
+ break;
+@@ -1754,7 +1869,7 @@ static int remove_item(Item *i) {
+ case REMOVE_PATH:
+ case TRUNCATE_DIRECTORY:
+ case RECURSIVE_REMOVE_PATH:
+- return glob_item(i, remove_item_instance, false);
++ return glob_item(i, remove_item_instance);
+
+ default:
+ return 0;
+@@ -1828,7 +1943,7 @@ static int clean_item(Item *i) {
+ return 0;
+ case EMPTY_DIRECTORY:
+ case IGNORE_DIRECTORY_PATH:
+- return glob_item(i, clean_item_instance, false);
++ return glob_item(i, clean_item_instance);
+ default:
+ return 0;
+ }
+--
+2.11.0
+