mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
chase: when chasing paths, trigger automounts
As it turns out open() with O_PATH does *not* trigger autofs, you get a reference to the autofs inode, if not triggered. But there's a way out: open_tree() (when specified without OPEN_TREE_CLONE) is actually fully equivalent to open() with O_PATH – with the exception of one thing: it *does* trigger automounts. Thanks for Christian Brauner for pointing me to this and saving my day. Fixes: #33155
This commit is contained in:
committed by
Luca Boccassi
parent
0754db571b
commit
c5de7b14ae
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <linux/magic.h>
|
||||
#include <sys/mount.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
@@ -370,8 +371,22 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Otherwise let's see what this is. */
|
||||
child = r = RET_NERRNO(openat(fd, first, O_CLOEXEC|O_NOFOLLOW|O_PATH));
|
||||
/* Otherwise let's pin it by file descriptor, via O_PATH. 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 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.
|
||||
*
|
||||
* As it turns out some sandboxes prohibit open_tree(), and return EPERM or ENOSYS if we call
|
||||
* it. But since autofs does not work inside of mount namespace anyway, let's simply handle
|
||||
* this as gracefully as we can, and fall back to classic openat() if we see EPERM/ENOSYS. */
|
||||
if (FLAGS_SET(flags, CHASE_NO_AUTOFS))
|
||||
r = -EPERM;
|
||||
else
|
||||
child = r = RET_NERRNO(open_tree(fd, first, AT_SYMLINK_NOFOLLOW|OPEN_TREE_CLOEXEC));
|
||||
if (r == -EPERM || ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
child = r = RET_NERRNO(openat(fd, first, O_CLOEXEC|O_NOFOLLOW|O_PATH));
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user