[PATCH 038/112] fs: implement O_CHROOT
Ahmad Fatoum
a.fatoum at pengutronix.de
Wed Jan 3 10:11:58 PST 2024
For use by EFI file system path resolution, implement an O_CHROOT
flag that will map / to the root of the file system the dirfd points
to instead of the VFS root. If the dirfd points to a mountpoint, it will
be followed to the file system inside. This is similar to Linux openat2
with RESOLVE_IN_ROOT.
Without this, the EFI protocol would have to do path sanitization itself
before passing paths to the barebox VFS implementation.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
fs/fs.c | 19 +++++++++++++++++--
include/fcntl.h | 1 +
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/fs/fs.c b/fs/fs.c
index 7fc638451f13..5f46918caafe 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -2166,9 +2166,17 @@ static int link_path_walk(const char *name, struct nameidata *nd)
}
}
+static bool file_has_flag(FILE *f, unsigned flag)
+{
+ if (IS_ERR_OR_NULL(f))
+ return false;
+ return (f->flags & flag) == flag;
+}
+
static const char *path_init(int dirfd, struct nameidata *nd, unsigned flags)
{
const char *s = nd->name->name;
+ bool chroot = false;
FILE *f = NULL;
nd->last_type = LAST_ROOT; /* if there are only slashes... */
@@ -2181,10 +2189,12 @@ static const char *path_init(int dirfd, struct nameidata *nd, unsigned flags)
/* We don't check for error here yet, as POSIX allows checking
* whether paths are absolute with openat(-1, path, O_PATH)
*/
- if (dirfd != AT_FDCWD)
+ if (dirfd != AT_FDCWD) {
f = fd_to_file(dirfd, true);
+ chroot = file_has_flag(f, O_CHROOT);
+ }
- if (*s == '/') {
+ if (*s == '/' && !chroot) {
get_root(&nd->path);
} else if (dirfd == AT_FDCWD) {
get_pwd(&nd->path);
@@ -2195,6 +2205,11 @@ static const char *path_init(int dirfd, struct nameidata *nd, unsigned flags)
nd->path.mnt = &f->fsdev->vfsmount;
nd->path.dentry = f->dentry;
follow_mount(&nd->path);
+
+ if (*s == '/')
+ nd->path.dentry = nd->path.mnt->mnt_root;
+ if (chroot)
+ nd->d_root = nd->path.mnt->mnt_root;
}
return s;
diff --git a/include/fcntl.h b/include/fcntl.h
index a3f5d96cd0ac..532a3a0f6b1e 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -24,6 +24,7 @@
#define O_DIRECTORY 00200000 /* must be a directory */
#define O_NOFOLLOW 00400000 /* don't follow links */
#define O_PATH 02000000 /* open as path */
+#define O_CHROOT 04000000 /* dirfd: stay within filesystem root */
#define __O_TMPFILE 020000000
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
--
2.39.2
More information about the barebox
mailing list