Re: [PATCH v3 3/4] add statmount(2) syscall
From: Paul Moore <paul@paul-moore.com>
Date: 2023-10-04 19:26:40
Also in:
linux-fsdevel, linux-man, linux-security-module, lkml
On Thu, Sep 28, 2023 at 9:03 AM Miklos Szeredi [off-list ref] wrote:
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> --- arch/x86/entry/syscalls/syscall_32.tbl | 1 + arch/x86/entry/syscalls/syscall_64.tbl | 1 + fs/namespace.c | 283 +++++++++++++++++++++++++ fs/statfs.c | 1 + include/linux/syscalls.h | 5 + include/uapi/asm-generic/unistd.h | 5 +- include/uapi/linux/mount.h | 56 +++++ 7 files changed, 351 insertions(+), 1 deletion(-)
...
quoted hunk ↗ jump to hunk
diff --git a/fs/namespace.c b/fs/namespace.c index c3a41200fe70..3326ba2b2810 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;Thank you for adding the security_sb_statfs() call to this operation, however I believe we want to place it *after* the capability check to be consistent with other LSM calls.
+ if (!capable(CAP_SYS_ADMIN) && + !is_path_reachable(m, m->mnt.mnt_root, &s->root)) + return -EPERM; + + 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