diff options
| author | Christian Brauner <brauner@kernel.org> | 2025-10-16 07:59:15 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-10-19 16:34:02 +0200 |
| commit | fa1974fad4bc1a82a5ed96aa75c191f5d966701f (patch) | |
| tree | e94e89f629f81a63478166900b4239a70e9b1d67 /fs | |
| parent | 32c258aad47ef9c58c8ae50e160b9c94c43f3829 (diff) | |
| download | linux-fa1974fad4bc1a82a5ed96aa75c191f5d966701f.tar.gz linux-fa1974fad4bc1a82a5ed96aa75c191f5d966701f.tar.bz2 linux-fa1974fad4bc1a82a5ed96aa75c191f5d966701f.zip | |
statmount: don't call path_put() under namespace semaphore
[ Upstream commit e8c84e2082e69335f66c8ade4895e80ec270d7c4 ]
Massage statmount() and make sure we don't call path_put() under the
namespace semaphore. If we put the last reference we're fscked.
Fixes: 46eae99ef733 ("add statmount(2) syscall")
Cc: stable@vger.kernel.org # v6.8+
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/namespace.c | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 2bfb091729fc..760696941249 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5200,7 +5200,6 @@ static int grab_requested_root(struct mnt_namespace *ns, struct path *root) static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id, struct mnt_namespace *ns) { - struct path root __free(path_put) = {}; struct mount *m; int err; @@ -5212,7 +5211,7 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id, if (!s->mnt) return -ENOENT; - err = grab_requested_root(ns, &root); + err = grab_requested_root(ns, &s->root); if (err) return err; @@ -5221,15 +5220,13 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id, * mounts to show users. */ m = real_mount(s->mnt); - if (!is_path_reachable(m, m->mnt.mnt_root, &root) && + if (!is_path_reachable(m, m->mnt.mnt_root, &s->root) && !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) return -EPERM; err = security_sb_statfs(s->mnt->mnt_root); if (err) return err; - - s->root = root; if (s->mask & STATMOUNT_SB_BASIC) statmount_sb_basic(s); @@ -5406,6 +5403,7 @@ retry: if (!ret) ret = copy_statmount_to_user(ks); kvfree(ks->seq.buf); + path_put(&ks->root); if (retry_statmount(ret, &seq_size)) goto retry; return ret; |
