Skip to content

Commit 78f0e33

Browse files
avaginbrauner
authored andcommitted
fs/namespace: correctly handle errors returned by grab_requested_mnt_ns
grab_requested_mnt_ns was changed to return error codes on failure, but its callers were not updated to check for error pointers, still checking only for a NULL return value. This commit updates the callers to use IS_ERR() or IS_ERR_OR_NULL() and PTR_ERR() to correctly check for and propagate errors. This also makes sure that the logic actually works and mount namespace file descriptors can be used to refere to mounts. Christian Brauner <brauner@kernel.org> says: Rework the patch to be more ergonomic and in line with our overall error handling patterns. Fixes: 7b9d14a ("fs: allow mount namespace fd") Cc: Christian Brauner <brauner@kernel.org> Signed-off-by: Andrei Vagin <avagin@google.com> Link: https://patch.msgid.link/20251111062815.2546189-1-avagin@google.com Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent a3f8f86 commit 78f0e33

File tree

2 files changed

+17
-17
lines changed

2 files changed

+17
-17
lines changed

fs/namespace.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ static void mnt_ns_release(struct mnt_namespace *ns)
141141
kfree(ns);
142142
}
143143
}
144-
DEFINE_FREE(mnt_ns_release, struct mnt_namespace *, if (_T) mnt_ns_release(_T))
144+
DEFINE_FREE(mnt_ns_release, struct mnt_namespace *,
145+
if (!IS_ERR(_T)) mnt_ns_release(_T))
145146

146147
static void mnt_ns_release_rcu(struct rcu_head *rcu)
147148
{
@@ -5726,7 +5727,7 @@ static int copy_mnt_id_req(const struct mnt_id_req __user *req,
57265727
ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize);
57275728
if (ret)
57285729
return ret;
5729-
if (kreq->spare != 0)
5730+
if (kreq->mnt_ns_fd != 0 && kreq->mnt_ns_id)
57305731
return -EINVAL;
57315732
/* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */
57325733
if (kreq->mnt_id <= MNT_UNIQUE_ID_OFFSET)
@@ -5743,16 +5744,12 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
57435744
{
57445745
struct mnt_namespace *mnt_ns;
57455746

5746-
if (kreq->mnt_ns_id && kreq->spare)
5747-
return ERR_PTR(-EINVAL);
5748-
5749-
if (kreq->mnt_ns_id)
5750-
return lookup_mnt_ns(kreq->mnt_ns_id);
5751-
5752-
if (kreq->spare) {
5747+
if (kreq->mnt_ns_id) {
5748+
mnt_ns = lookup_mnt_ns(kreq->mnt_ns_id);
5749+
} else if (kreq->mnt_ns_fd) {
57535750
struct ns_common *ns;
57545751

5755-
CLASS(fd, f)(kreq->spare);
5752+
CLASS(fd, f)(kreq->mnt_ns_fd);
57565753
if (fd_empty(f))
57575754
return ERR_PTR(-EBADF);
57585755

@@ -5767,6 +5764,8 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
57675764
} else {
57685765
mnt_ns = current->nsproxy->mnt_ns;
57695766
}
5767+
if (!mnt_ns)
5768+
return ERR_PTR(-ENOENT);
57705769

57715770
refcount_inc(&mnt_ns->passive);
57725771
return mnt_ns;
@@ -5791,8 +5790,8 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
57915790
return ret;
57925791

57935792
ns = grab_requested_mnt_ns(&kreq);
5794-
if (!ns)
5795-
return -ENOENT;
5793+
if (IS_ERR(ns))
5794+
return PTR_ERR(ns);
57965795

57975796
if (kreq.mnt_ns_id && (ns != current->nsproxy->mnt_ns) &&
57985797
!ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN))
@@ -5902,8 +5901,8 @@ static void __free_klistmount_free(const struct klistmount *kls)
59025901
static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req *kreq,
59035902
size_t nr_mnt_ids)
59045903
{
5905-
59065904
u64 last_mnt_id = kreq->param;
5905+
struct mnt_namespace *ns;
59075906

59085907
/* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */
59095908
if (last_mnt_id != 0 && last_mnt_id <= MNT_UNIQUE_ID_OFFSET)
@@ -5917,9 +5916,10 @@ static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req *
59175916
if (!kls->kmnt_ids)
59185917
return -ENOMEM;
59195918

5920-
kls->ns = grab_requested_mnt_ns(kreq);
5921-
if (!kls->ns)
5922-
return -ENOENT;
5919+
ns = grab_requested_mnt_ns(kreq);
5920+
if (IS_ERR(ns))
5921+
return PTR_ERR(ns);
5922+
kls->ns = ns;
59235923

59245924
kls->mnt_parent_id = kreq->mnt_id;
59255925
return 0;

include/uapi/linux/mount.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ struct statmount {
197197
*/
198198
struct mnt_id_req {
199199
__u32 size;
200-
__u32 spare;
200+
__u32 mnt_ns_fd;
201201
__u64 mnt_id;
202202
__u64 param;
203203
__u64 mnt_ns_id;

0 commit comments

Comments
 (0)