diff options
author | Christian Brauner <brauner@kernel.org> | 2024-07-19 13:41:49 +0200 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2024-08-09 12:44:49 +0200 |
commit | 7b9d14af8777ac439bbfa9ac73a12a6d85289e7e (patch) | |
tree | 92e4b7b1f31a854329f561e604d424030001cf89 /fs/namespace.c | |
parent | 720261cfc7329406a50c2a8536e0039b9dd9a4e5 (diff) | |
download | lwn-7b9d14af8777ac439bbfa9ac73a12a6d85289e7e.tar.gz lwn-7b9d14af8777ac439bbfa9ac73a12a6d85289e7e.zip |
fs: allow mount namespace fd
We already allow a mount namespace id, enable mount namespace file
descriptors as well.
Link: https://lore.kernel.org/r/20240719-work-mount-namespace-v1-2-834113cab0d2@kernel.org
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 221db9de4729..1a0b9e3089a2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5243,12 +5243,37 @@ static int copy_mnt_id_req(const struct mnt_id_req __user *req, * that, or if not simply grab a passive reference on our mount namespace and * return that. */ -static struct mnt_namespace *grab_requested_mnt_ns(u64 mnt_ns_id) +static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq) { - if (mnt_ns_id) - return lookup_mnt_ns(mnt_ns_id); - refcount_inc(¤t->nsproxy->mnt_ns->passive); - return current->nsproxy->mnt_ns; + struct mnt_namespace *mnt_ns; + + if (kreq->mnt_ns_id && kreq->spare) + return ERR_PTR(-EINVAL); + + if (kreq->mnt_ns_id) + return lookup_mnt_ns(kreq->mnt_ns_id); + + if (kreq->spare) { + struct ns_common *ns; + + CLASS(fd, f)(kreq->spare); + if (!f.file) + return ERR_PTR(-EBADF); + + if (!proc_ns_file(f.file)) + return ERR_PTR(-EINVAL); + + ns = get_proc_ns(file_inode(f.file)); + if (ns->ops->type != CLONE_NEWNS) + return ERR_PTR(-EINVAL); + + mnt_ns = to_mnt_ns(ns); + } else { + mnt_ns = current->nsproxy->mnt_ns; + } + + refcount_inc(&mnt_ns->passive); + return mnt_ns; } SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, @@ -5269,7 +5294,7 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, if (ret) return ret; - ns = grab_requested_mnt_ns(kreq.mnt_ns_id); + ns = grab_requested_mnt_ns(&kreq); if (!ns) return -ENOENT; @@ -5396,7 +5421,7 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req, if (!kmnt_ids) return -ENOMEM; - ns = grab_requested_mnt_ns(kreq.mnt_ns_id); + ns = grab_requested_mnt_ns(&kreq); if (!ns) return -ENOENT; |