Since https://github.com/systemd/systemd/commit/
c5de7b14ae2e08d267d8d75bc88934ac6aa7dcd6
file searching implies a new mount api syscall by default,
to trigger automounts.
This is problematic in NSS plugins, as they are dlopen'ed inside
processes by glibc, for two reasons.
First of all, potentially searching on a networked filesystem
automount could lead to nasty surprises, such as the process
responsible for setting up the network filesystem trying to
search on that same filesystem.
More importantly, the new mount api syscall was never part of
the filesystem seccomp filter that we provide by default, and
given mounting/remounting/bind mounting is one of the possible
ways to bypass sandboxing it is very likely not allowed when
custom filters are used in sandboxed processes, if they don't
need to do these operations otherwise.
The filesystem seccomp mask we provide has been updated, however
this only takes effect on the next restart of a service. When
systemd is upgraded via a package upgrade, the new nss plugin is
installed and will be immediately dlopen'ed by glibc when needed,
without waiting for the process to restart, which means the existing
seccomp filter applies, causing the filter to trigger.
Given it's not really possible for any arbitrary program to
predict which NSS modules glibc will load, given programs do not
configure that and instead nsswitch is set up by the sysadmin,
it's impossible to handle at each process level. It's also not
possible to know when it will be triggered, given the plugin
is not linked in each binary tools like need-restart cannot
even pre-emptively restart services that may be affected.
This means in practice, upgrading from systemd << v258 to >= v258
requires a reboot to avoid either subtle or catastrophic system
failures.
By avoiding to trigger automounts in nss-systemd we can avoid
both issues.
userdb drop-ins are searched for in:
/etc/userdb/
/run/userdb/
/run/host/userdb/
/usr/local/lib/userdb/
/usr/lib/userdb/
none of which are supported as automounts anyway.
Note that this happens only when the userdbd service is not running,
as otherwise nss-systemd will go through the varlink IPC, rather than
doing the searches in-process.
So invert CHASE_NO_AUTOFS to CHASE_AUTOFS and set it in the places where
we do want to trigger automounts, like looking for the ESP.
Follow-up for https://github.com/systemd/systemd/commit/
c5de7b14ae2e08d267d8d75bc88934ac6aa7dcd6
Fixes https://github.com/systemd/systemd/issues/38565
findmnt
getent
getfacl
+ groups
id
integritysetup
iscsid
/* Pin an inode via O_PATH semantics. Sounds pretty obvious to do this, right? You just do open()
* with O_PATH, and there you go. But uh, it's not that easy. open() via O_PATH does not trigger
- * automounts, but we usually want that (except if CHASE_NO_AUTOFS is used). But thankfully there's
+ * automounts, but we usually want that (when CHASE_AUTOFS is used). But thankfully there's
* a way out: the newer open_tree() call, when specified without OPEN_TREE_CLONE actually is fully
* equivalent to open() with O_PATH – except for one thing: it triggers automounts.
*
* -ENOLINK. If CHASE_WARN is also set, a warning describing the unsafe transition is emitted.
* CHASE_WARN cannot be used in PID 1.
*
- * 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, path normalization
+ * 5. Without CHASE_AUTOFS: in this case if an autofs mount point is encountered, path normalization
* is aborted and -EREMOTE is returned. If CHASE_WARN is also set, a warning showing the path of
* the mount point is emitted. CHASE_WARN cannot be used in PID 1.
*/
}
if (!(flags &
- (CHASE_AT_RESOLVE_IN_ROOT|CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_STEP|
+ (CHASE_AT_RESOLVE_IN_ROOT|CHASE_NONEXISTENT|CHASE_AUTOFS|CHASE_SAFE|CHASE_STEP|
CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_PARENT)) &&
!ret_path && ret_fd) {
}
/* Otherwise let's pin it by file descriptor, via O_PATH. */
- child = r = openat_opath_with_automount(fd, first, /* automount = */ !FLAGS_SET(flags, CHASE_NO_AUTOFS));
+ child = r = openat_opath_with_automount(fd, first, /* automount = */ FLAGS_SET(flags, CHASE_AUTOFS));
if (r < 0) {
if (r != -ENOENT)
return r;
unsafe_transition(&st, &st_child))
return log_unsafe_transition(fd, child, path, flags);
- if (FLAGS_SET(flags, CHASE_NO_AUTOFS) &&
+ if (!FLAGS_SET(flags, CHASE_AUTOFS) &&
fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
return log_autofs_mount_point(child, path, flags);
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
if (empty_or_root(root) && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
return xopenat_full(AT_FDCWD, path,
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
assert(ret_dir);
if (empty_or_root(root) && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) {
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) {
/* Shortcut this call if none of the special features of this call are requested */
d = opendir(path);
if (!d)
assert(ret_stat);
if (empty_or_root(root) && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(fstatat(AT_FDCWD, path, ret_stat,
FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0));
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
if (empty_or_root(root) && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(faccessat(AT_FDCWD, path, access_mode,
FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0));
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
if (dir_fd == AT_FDCWD && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
return xopenat_full(dir_fd, path,
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
assert(ret_dir);
if (dir_fd == AT_FDCWD && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) {
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0) {
/* Shortcut this call if none of the special features of this call are requested */
d = opendir(path);
if (!d)
assert(ret_stat);
if (dir_fd == AT_FDCWD && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(fstatat(AT_FDCWD, path, ret_stat,
FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0));
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
if (dir_fd == AT_FDCWD && !ret_path &&
- (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
+ (chase_flags & (CHASE_AUTOFS|CHASE_SAFE|CHASE_PROHIBIT_SYMLINKS|CHASE_PARENT|CHASE_MKDIR_0755)) == 0)
/* Shortcut this call if none of the special features of this call are requested */
return RET_NERRNO(faccessat(AT_FDCWD, path, access_mode,
FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0));
typedef enum ChaseFlags {
CHASE_PREFIX_ROOT = 1 << 0, /* The specified path will be prefixed by the specified root before beginning the iteration */
CHASE_NONEXISTENT = 1 << 1, /* It's OK if the path doesn't actually exist. */
- CHASE_NO_AUTOFS = 1 << 2, /* Return -EREMOTE if autofs mount point found */
+ CHASE_AUTOFS = 1 << 2, /* Trigger automount if autofs mount point found instead of returning -EREMOTE */
CHASE_SAFE = 1 << 3, /* Return -EPERM if we ever traverse from unprivileged to privileged files or directories */
CHASE_TRAIL_SLASH = 1 << 4, /* Any trailing slash will be preserved */
CHASE_STEP = 1 << 5, /* Just execute a single step of the normalization */
assert(esp_path);
assert(source_path);
- r = chase_and_opendir("/EFI/BOOT", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &p, &d);
+ r = chase_and_opendir("/EFI/BOOT", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, &p, &d);
if (r == -ENOENT)
return 0;
if (r < 0)
if (!p)
return log_oom();
- r = chase(p, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &source_path, NULL);
+ r = chase(p, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, &source_path, NULL);
/* If we had a root directory to try, we didn't find it and we are in auto mode, retry on the host */
if (r == -ENOENT && root && arg_install_source == ARG_INSTALL_SOURCE_AUTO)
- r = chase(p, NULL, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &source_path, NULL);
+ r = chase(p, NULL, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, &source_path, NULL);
if (r < 0)
return log_error_errno(r,
"Failed to resolve path %s%s%s: %m",
if (!q)
return log_oom();
- r = chase(q, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_NONEXISTENT, &dest_path, NULL);
+ r = chase(q, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_NONEXISTENT|CHASE_AUTOFS, &dest_path, NULL);
if (r < 0)
return log_error_errno(r, "Failed to resolve path %s under directory %s: %m", q, esp_path);
v = strjoina("/EFI/BOOT/BOOT", e);
ascii_strupper(strrchr(v, '/') + 1);
- r = chase(v, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_NONEXISTENT, &default_dest_path, NULL);
+ r = chase(v, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_NONEXISTENT|CHASE_AUTOFS, &default_dest_path, NULL);
if (r < 0)
return log_error_errno(r, "Failed to resolve path %s under directory %s: %m", v, esp_path);
_cleanup_free_ char *path = NULL;
int r;
- r = chase_and_opendir(BOOTLIBDIR, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &path, &d);
+ r = chase_and_opendir(BOOTLIBDIR, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, &path, &d);
/* If we had a root directory to try, we didn't find it and we are in auto mode, retry on the host */
if (r == -ENOENT && root && arg_install_source == ARG_INSTALL_SOURCE_AUTO)
- r = chase_and_opendir(BOOTLIBDIR, NULL, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &path, &d);
+ r = chase_and_opendir(BOOTLIBDIR, NULL, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, &path, &d);
if (r == -ENOENT && arg_graceful) {
log_debug("Source directory does not exist, ignoring.");
return 0;
if (r < 0)
return r;
- _cleanup_close_ int keys_fd = chase_and_open("loader/keys/auto", esp, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, O_DIRECTORY, NULL);
+ _cleanup_close_ int keys_fd = chase_and_open("loader/keys/auto", esp, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, O_DIRECTORY, NULL);
if (keys_fd < 0)
return log_error_errno(keys_fd, "Failed to chase loader/keys/auto in the ESP: %m");
uint16_t slot;
int r;
- r = chase_and_access(path, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, F_OK, NULL);
+ r = chase_and_access(path, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, F_OK, NULL);
if (r == -ENOENT)
return 0;
if (r < 0)
_cleanup_free_ char *p = NULL;
int r, c = 0;
- r = chase_and_opendir("/EFI/BOOT", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &p, &d);
+ r = chase_and_opendir("/EFI/BOOT", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, &p, &d);
if (r == -ENOENT)
return 0;
if (r < 0)
assert(previous);
assert(is_first);
- r = chase_and_opendir(path, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, &p, &d);
+ r = chase_and_opendir(path, esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, &p, &d);
if (r == -ENOENT)
return 0;
if (r < 0)
return;
if (arg_dry_run) {
- r = chase_and_access(fn, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, F_OK, &path);
+ r = chase_and_access(fn, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, F_OK, &path);
if (r < 0)
log_info_errno(r, "Unable to determine whether \"%s\" exists, ignoring: %m", fn);
else
return;
}
- r = chase_and_unlink(fn, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, 0, &path);
+ r = chase_and_unlink(fn, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, 0, &path);
if (r >= 0)
log_info("Removed \"%s\"", path);
else if (r != -ENOENT)
_cleanup_free_ char *d = NULL;
if (path_extract_directory(fn, &d) >= 0 && !path_equal(d, "/")) {
- r = chase_and_unlink(d, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, AT_REMOVEDIR, NULL);
+ r = chase_and_unlink(d, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, AT_REMOVEDIR, NULL);
if (r < 0 && !IN_SET(r, -ENOTEMPTY, -ENOENT))
log_warning_errno(r, "Failed to remove directory \"%s\", ignoring: %m", d);
}
if (arg_dry_run)
log_info("Would remove \"%s\"", e->path);
else {
- r = chase_and_unlink(e->path, root, CHASE_PROHIBIT_SYMLINKS, 0, NULL);
+ r = chase_and_unlink(e->path, root, CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS, 0, NULL);
if (r < 0)
return log_error_errno(r, "Failed to remove \"%s\": %m", e->path);
if (r < 0)
return log_error_errno(r, "Failed to count files in %s: %m", root);
- dir_fd = chase_and_open(arg_entry_token, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS,
+ dir_fd = chase_and_open(arg_entry_token, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS|CHASE_AUTOFS,
O_DIRECTORY|O_CLOEXEC, &full);
if (dir_fd == -ENOENT)
return 0;
* since they all support the private/ symlink logic at least in some
* configurations, see above. */
- r = chase(target, NULL, 0, &target_resolved, NULL);
+ r = chase(target, NULL, CHASE_AUTOFS, &target_resolved, NULL);
if (r < 0)
goto fail;
}
/* /var/lib or friends may be symlinks. So, let's chase them also. */
- r = chase(q, NULL, CHASE_NONEXISTENT, &q_resolved, NULL);
+ r = chase(q, NULL, CHASE_NONEXISTENT|CHASE_AUTOFS, &q_resolved, NULL);
if (r < 0)
goto fail;
r = chase(wd,
runtime->ephemeral_copy ?: context->root_directory,
- CHASE_PREFIX_ROOT|CHASE_AT_RESOLVE_IN_ROOT,
+ CHASE_PREFIX_ROOT|CHASE_AT_RESOLVE_IN_ROOT|CHASE_AUTOFS,
/* ret_path= */ NULL,
&dfd);
if (r >= 0)
/* Validate that the path we are overmounting does not contain any symlinks, because if it does, we
* couldn't support that reasonably: the mounts in /proc/self/mountinfo would not be recognizable to
* us anymore. */
- fd = chase_and_open_parent(m->where, /* root= */ NULL, CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755, &fn);
+ fd = chase_and_open_parent(m->where, /* root= */ NULL, CHASE_PROHIBIT_SYMLINKS|CHASE_MKDIR_0755|CHASE_AUTOFS, &fn);
if (fd == -EREMCHG) {
r = unit_log_noncanonical_mount_path(UNIT(m), m->where);
goto fail;
* a time by specifying CHASE_STEP. This function returns 0 if we resolved one step, and > 0 if we reached the
* end and already have a fully normalized name. */
- r = chase(mount_entry_path(m), root_directory, CHASE_STEP|CHASE_NONEXISTENT, &target, NULL);
+ r = chase(mount_entry_path(m), root_directory, CHASE_STEP|CHASE_NONEXISTENT|CHASE_AUTOFS, &target, NULL);
if (r < 0)
return log_debug_errno(r, "Failed to chase symlinks '%s': %m", mount_entry_path(m));
if (r > 0) /* Reached the end, nothing more to resolve */
return log_error_errno(r, "Failed to set label of the source directory %s: %m", mount_entry_source(m));
}
- r = chase(mount_entry_source(m), NULL, CHASE_TRAIL_SLASH, &chased, NULL);
+ r = chase(mount_entry_source(m), NULL, CHASE_TRAIL_SLASH|CHASE_AUTOFS, &chased, NULL);
if (r == -ENOENT && m->ignore) {
log_debug_errno(r, "Path %s does not exist, ignoring.", mount_entry_source(m));
return 0;
assert(path);
if (fd < 0) {
- r = chase(path, /* root= */ NULL, CHASE_TRAIL_SLASH|CHASE_MUST_BE_DIRECTORY, /* ret_path= */ NULL, &dfd);
+ r = chase(path, /* root= */ NULL, CHASE_TRAIL_SLASH|CHASE_MUST_BE_DIRECTORY|CHASE_AUTOFS, /* ret_path= */ NULL, &dfd);
if (r < 0)
return r;
fd = dfd;
return -ENODATA;
_cleanup_free_ char *path = NULL;
- r = chase(c->path, s->exec_context.root_directory, CHASE_PREFIX_ROOT, &path, NULL);
+ r = chase(c->path, s->exec_context.root_directory, CHASE_PREFIX_ROOT|CHASE_AUTOFS, &path, NULL);
if (r < 0) {
log_unit_debug_errno(UNIT(s), r, "Failed to resolve service binary '%s', ignoring.", c->path);
return -ENODATA;
_cleanup_free_ char *resolved = NULL;
_cleanup_close_ int fd = -EBADF;
- r = chase(path, /* root = */ NULL, CHASE_NO_AUTOFS | flags, &resolved, ret_fd ? &fd : NULL);
+ r = chase(path, /* root = */ NULL, flags, &resolved, ret_fd ? &fd : NULL);
if (r < 0)
return r;
assert(ret_where);
if (arg_transport == BUS_TRANSPORT_LOCAL && arg_canonicalize) {
- r = chase(input, /* root= */ NULL, CHASE_NONEXISTENT, ret_where, /* ret_fd= */ NULL);
+ r = chase(input, /* root= */ NULL, CHASE_NONEXISTENT|CHASE_AUTOFS, ret_where, /* ret_fd= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to make path %s absolute: %m", input);
} else {
}
if (arg_transport == BUS_TRANSPORT_LOCAL && arg_canonicalize) {
- r = chase(p, /* root= */ NULL, /* flags= */ 0, &arg_mount_what, /* ret_fd= */ NULL);
+ r = chase(p, /* root= */ NULL, CHASE_AUTOFS, &arg_mount_what, /* ret_fd= */ NULL);
if (r < 0)
return log_error_errno(r, "Failed to chase path '%s': %m", p);
} else {
return log_oom();
_cleanup_close_ int fd = -EBADF;
- r = chase(u, /* root= */ NULL, 0, &p, &fd);
+ r = chase(u, /* root= */ NULL, CHASE_AUTOFS, &p, &fd);
if (r < 0) {
RET_GATHER(ret, log_error_errno(r, "Failed to chase path '%s': %m", u));
continue;
struct stat stb;
const char *e;
- r = chase(s, NULL, CHASE_SAFE, &q, &dir_fd);
+ r = chase(s, NULL, CHASE_SAFE|CHASE_AUTOFS, &q, &dir_fd);
if (r == -ENOENT)
continue;
if (r < 0) {
if (!filename_is_valid(e))
continue;
- r = chaseat(dir_fd, e, CHASE_SAFE, NULL, &inode_fd);
+ r = chaseat(dir_fd, e, CHASE_SAFE|CHASE_AUTOFS, NULL, &inode_fd);
if (r < 0)
return log_error_errno(r, "Couldn't verify that specified image '%s' is in search path '%s': %m", p, s);
/* Non-root user can only check the status, so if an error occurred in the following, it does not cause any
* issues. Let's also, silence the error messages. */
- r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_PARENT, &p, &pfd);
+ r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_PARENT|CHASE_AUTOFS, &p, &pfd);
if (r < 0)
return log_full_errno((searching && r == -ENOENT) ||
(unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR,
"$SYSTEMD_ESP_PATH does not refer to an absolute path, refusing to use it: %s",
path);
- r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT, &p, &fd);
+ r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_AUTOFS, &p, &fd);
if (r < 0)
return log_error_errno(r, "Failed to resolve path %s: %m", path);
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(path);
- r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_PARENT, &p, &pfd);
+ r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_PARENT|CHASE_AUTOFS, &p, &pfd);
if (r < 0)
return log_full_errno((searching && r == -ENOENT) ||
(unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR,
"$SYSTEMD_XBOOTLDR_PATH does not refer to an absolute path, refusing to use it: %s",
path);
- r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT, &p, &fd);
+ r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT|CHASE_AUTOFS, &p, &fd);
if (r < 0)
return log_error_errno(r, "Failed to resolve path %s: %m", p);
_cleanup_free_ char *resolved = NULL;
struct stat st;
- r = chase(rr->path, root, CHASE_PREFIX_ROOT, &resolved, &fd);
+ r = chase(rr->path, root, CHASE_PREFIX_ROOT|CHASE_AUTOFS, &resolved, &fd);
if (r < 0)
return log_error_errno(r, "Failed to resolve '%s': %m", rr->path);
} else if (RESOURCE_IS_FILESYSTEM(rr->type)) {
_cleanup_free_ char *resolved = NULL, *relative_to = NULL;
- ChaseFlags chase_flags = CHASE_NONEXISTENT | CHASE_PREFIX_ROOT;
+ ChaseFlags chase_flags = CHASE_NONEXISTENT | CHASE_PREFIX_ROOT | CHASE_AUTOFS;
if (rr->path_relative_to == PATH_RELATIVE_TO_EXPLICIT) {
assert(relative_to_directory);
assert_not_reached();
if (resolve_link_path && root) {
- r = chase(link_path, root, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &resolved, NULL);
+ r = chase(link_path, root, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT|CHASE_AUTOFS, &resolved, NULL);
if (r < 0)
return log_error_errno(r, "Failed to resolve current symlink path '%s': %m", link_path);
_cleanup_closedir_ DIR *d = NULL;
_cleanup_free_ char *p = NULL;
- r = chase_and_opendir(*i, arg_root, CHASE_PREFIX_ROOT, &p, &d);
+ r = chase_and_opendir(*i, arg_root, CHASE_PREFIX_ROOT|CHASE_AUTOFS, &p, &d);
if (r == -ENOENT)
continue;
if (r < 0)
{ "prefix-root", no_argument, NULL, CHASE_PREFIX_ROOT },
{ "nonexistent", no_argument, NULL, CHASE_NONEXISTENT },
- { "no_autofs", no_argument, NULL, CHASE_NO_AUTOFS },
+ { "autofs", no_argument, NULL, CHASE_AUTOFS },
{ "safe", no_argument, NULL, CHASE_SAFE },
{ "trail-slash", no_argument, NULL, CHASE_TRAIL_SLASH },
{ "step", no_argument, NULL, CHASE_STEP },
case CHASE_PREFIX_ROOT:
case CHASE_NONEXISTENT:
- case CHASE_NO_AUTOFS:
+ case CHASE_AUTOFS:
case CHASE_SAFE:
case CHASE_TRAIL_SLASH:
case CHASE_STEP:
path,
allow_failure ? ", ignoring" : "");
- r = chase(dn, arg_root, allow_failure ? CHASE_SAFE : CHASE_SAFE|CHASE_WARN, NULL, &fd);
+ r = chase(dn, arg_root, allow_failure ? CHASE_SAFE|CHASE_AUTOFS : CHASE_SAFE|CHASE_WARN|CHASE_AUTOFS, NULL, &fd);
if (r == -ENOLINK) /* Unsafe symlink: already covered by CHASE_WARN */
return r;
if (r < 0)
if (!path_is_normalized(path))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to open invalid path '%s'.", path);
- r = chase(path, arg_root, CHASE_SAFE|CHASE_WARN|CHASE_NOFOLLOW, NULL, &fd);
+ r = chase(path, arg_root, CHASE_SAFE|CHASE_WARN|CHASE_NOFOLLOW|CHASE_AUTOFS, NULL, &fd);
if (r == -ENOLINK)
return r; /* Unsafe symlink: already covered by CHASE_WARN */
if (r < 0)
assert(i);
assert(i->type == EMPTY_DIRECTORY);
- r = chase(path, arg_root, CHASE_SAFE|CHASE_WARN, NULL, &fd);
+ r = chase(path, arg_root, CHASE_SAFE|CHASE_WARN|CHASE_AUTOFS, NULL, &fd);
if (r == -ENOLINK) /* Unsafe symlink: already covered by CHASE_WARN */
return r;
if (r == -ENOENT) {
assert(i);
if (i->ignore_if_target_missing) {
- r = chase(i->argument, arg_root, CHASE_SAFE|CHASE_PREFIX_ROOT|CHASE_NOFOLLOW, /* ret_path = */ NULL, /* ret_fd = */ NULL);
+ r = chase(i->argument, arg_root, CHASE_SAFE|CHASE_PREFIX_ROOT|CHASE_NOFOLLOW|CHASE_AUTOFS, /* ret_path = */ NULL, /* ret_fd = */ NULL);
if (r == -ENOENT) {
/* Silently skip over lines where the source file is missing. */
log_info("Symlink source path '%s/%s' does not exist, skipping line.",
path = _path;
}
- r = chase(path, arg_root, CHASE_NO_AUTOFS|CHASE_NONEXISTENT|CHASE_WARN, NULL, NULL);
+ r = chase(path, arg_root, CHASE_NONEXISTENT|CHASE_WARN|CHASE_AUTOFS, NULL, NULL);
if (r == -EREMOTE) {
log_notice_errno(r, "Skipping %s", i->path); /* We log the configured path, to not confuse the user. */
return 0;
userdbctl group root -j | userdbctl -F- group | cmp - <(userdbctl group root)
userdbctl group systemd-network -j | userdbctl -F- group | cmp - <(userdbctl group systemd-network)
userdbctl group 65534 -j | userdbctl -F- group | cmp - <(userdbctl group 65534)
+
+# Ensure NSS doesn't try to automount via open_tree
+if [[ ! -v ASAN_OPTIONS ]]; then
+ systemctl stop systemd-userdbd.socket systemd-userdbd.service
+ set +o pipefail
+ systemd-run -q -t --property SystemCallFilter=~open_tree id definitelynotarealuser | grep -q "no such user"
+ systemd-run -q -t --property SystemCallFilter=~open_tree id --groups definitelynotarealuser | grep -q "no such user"
+ systemd-run -q -t --property SystemCallFilter=~open_tree groups definitelynotarealuser | grep -q "no such user"
+ set -o pipefail
+ # getent shows no output when the entry is not found, but exists with 2, while sd-run crashing will exit
+ # with 1
+ assert_rc 2 systemd-run -q -t --property SystemCallFilter=~open_tree getent passwd definitelynotarealuser
+ assert_rc 2 systemd-run -q -t --property SystemCallFilter=~open_tree getent group definitelynotarealgroup
+ systemctl start systemd-userdbd.socket systemd-userdbd.service
+fi