Re: [PATCH v4 4/6] add statmount(2) syscall
From: Paul Moore <paul@paul-moore.com>
Date: 2023-11-08 02:58:24
Also in:
linux-fsdevel, linux-man, linux-security-module, lkml
On Oct 25, 2023 Miklos Szeredi [off-list ref] wrote:
quoted hunk ↗ jump to hunk
Add a way to query attributes of a single mount instead of having to parse the complete /proc/$PID/mountinfo, which might be huge. Lookup the mount the new 64bit mount ID. If a mount needs to be queried based on path, then statx(2) can be used to first query the mount ID belonging to the path. Design is based on a suggestion by Linus: "So I'd suggest something that is very much like "statfsat()", which gets a buffer and a length, and returns an extended "struct statfs" *AND* just a string description at the end." The interface closely mimics that of statx. Handle ASCII attributes by appending after the end of the structure (as per above suggestion). Pointers to strings are stored in u64 members to make the structure the same regardless of pointer size. Strings are nul terminated. Link: https://lore.kernel.org/all/CAHk-=wh5YifP7hzKSbwJj94+DZ2czjrZsczy6GBimiogZws=rg@mail.gmail.com/ (local) Signed-off-by: Miklos Szeredi <redacted> Reviewed-by: Ian Kent <raven@themaw.net> --- fs/namespace.c | 277 +++++++++++++++++++++++++++++++++++++ include/linux/syscalls.h | 5 + include/uapi/linux/mount.h | 56 ++++++++ 3 files changed, 338 insertions(+)diff --git a/fs/namespace.c b/fs/namespace.c index 7a33ea391a02..a980c250a3a6 100644 --- a/fs/namespace.c +++ b/fs/namespace.c
...
+static int do_statmount(struct stmt_state *s)
+{
+ struct statmnt *sm = &s->sm;
+ struct mount *m = real_mount(s->mnt);
+ size_t copysize = min_t(size_t, s->bufsize, sizeof(*sm));
+ int err;
+
+ err = security_sb_statfs(s->mnt->mnt_root);
+ if (err)
+ return err;
+
+ if (!capable(CAP_SYS_ADMIN) &&
+ !is_path_reachable(m, m->mnt.mnt_root, &s->root))
+ return -EPERM;In order to be consistent with our typical access control ordering, please move the security_sb_statfs() call down to here, after the capability checks.
+ stmt_numeric(s, STMT_SB_BASIC, stmt_sb_basic); + stmt_numeric(s, STMT_MNT_BASIC, stmt_mnt_basic); + stmt_numeric(s, STMT_PROPAGATE_FROM, stmt_propagate_from); + stmt_string(s, STMT_FS_TYPE, stmt_fs_type, &sm->fs_type); + stmt_string(s, STMT_MNT_ROOT, stmt_mnt_root, &sm->mnt_root); + stmt_string(s, STMT_MNT_POINT, stmt_mnt_point, &sm->mnt_point); + + if (s->err) + return s->err; + + /* Return the number of bytes copied to the buffer */ + sm->size = copysize + s->pos; + + if (copy_to_user(s->buf, sm, copysize)) + return -EFAULT; + + return 0; +}
-- paul-moore.com