On Wed, 4 Oct 2023 at 21:38, Paul Moore <paul@xxxxxxxxxxxxxx> wrote:
On Thu, Sep 28, 2023 at 9:04 AM Miklos Szeredi <mszeredi@xxxxxxxxxx> wrote:Hmm. Why is this specific to listing mounts (i.e. why doesn't readdir
Add way to query the children of a particular mount. This is a more...
flexible way to iterate the mount tree than having to parse the complete
/proc/self/mountinfo.
Lookup the mount by 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.
Return an array of new (64bit) mount ID's. Without privileges only mounts
are listed which are reachable from the task's root.
Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx>
---
arch/x86/entry/syscalls/syscall_32.tbl | 1 +
arch/x86/entry/syscalls/syscall_64.tbl | 1 +
fs/namespace.c | 69 ++++++++++++++++++++++++++
include/linux/syscalls.h | 3 ++
include/uapi/asm-generic/unistd.h | 5 +-
include/uapi/linux/mount.h | 3 ++
6 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/fs/namespace.c b/fs/namespace.cI believe we would want to move the security_sb_statfs() call from
index 3326ba2b2810..050e2d2af110 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -4970,6 +4970,75 @@ SYSCALL_DEFINE4(statmount, const struct __mount_arg __user *, req,
return ret;
}
+static long do_listmount(struct vfsmount *mnt, u64 __user *buf, size_t bufsize,
+ const struct path *root, unsigned int flags)
+{
+ struct mount *r, *m = real_mount(mnt);
+ struct path rootmnt = {
+ .mnt = root->mnt,
+ .dentry = root->mnt->mnt_root
+ };
+ long ctr = 0;
+ bool reachable_only = true;
+ int err;
+
+ err = security_sb_statfs(mnt->mnt_root);
+ if (err)
+ return err;
+
+ if (flags & LISTMOUNT_UNREACHABLE) {
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reachable_only = false;
+ }
+
+ if (reachable_only && !is_path_reachable(m, mnt->mnt_root, &rootmnt))
+ return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;
+
+ list_for_each_entry(r, &m->mnt_mounts, mnt_child) {
+ if (reachable_only &&
+ !is_path_reachable(r, r->mnt.mnt_root, root))
+ continue;
above to down here; something like this I think ...
err = security_sb_statfs(r->mnt.mnt_root);
if (err)
/* if we can't access the mount, pretend it doesn't exist */
continue;
have a similar filter)?
Also why hasn't this come up with regards to the proc interfaces that
list mounts?
I just want to understand the big picture here.
Thanks,
Miklos