Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -5365,6 +5365,12 @@ static int statmount_mnt_root(struct kstatmount *s, struct seq_file *seq)
return 0;
}

static int statmount_mnt_point_detached(struct kstatmount *s, struct seq_file *seq)
{
seq_puts(seq, "[detached]");
return 0;
}

static int statmount_mnt_point(struct kstatmount *s, struct seq_file *seq)
{
struct vfsmount *mnt = s->mnt;
Expand Down Expand Up @@ -5589,7 +5595,11 @@ static int statmount_string(struct kstatmount *s, u64 flag)
break;
case STATMOUNT_MNT_POINT:
offp = &sm->mnt_point;
ret = statmount_mnt_point(s, seq);
if (!s->root.mnt && !s->root.dentry)
/* detached mount case */
ret = statmount_mnt_point_detached(s, seq);
else
ret = statmount_mnt_point(s, seq);
break;
case STATMOUNT_MNT_OPTS:
offp = &sm->mnt_opts;
Expand Down Expand Up @@ -5736,24 +5746,29 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,
int err;

/* Has the namespace already been emptied? */
if (mnt_ns_id && mnt_ns_empty(ns))
if (!is_umount_ns(ns) && mnt_ns_id && mnt_ns_empty(ns))
return -ENOENT;

s->mnt = lookup_mnt_in_ns(mnt_id, ns);
if (!s->mnt)
return -ENOENT;

err = grab_requested_root(ns, &root);
if (err)
return err;
if (!is_umount_ns(ns)) {
err = grab_requested_root(ns, &root);
if (err)
return err;
}

/*
* Don't trigger audit denials. We just want to determine what
* mounts to show users.
*/
m = real_mount(s->mnt);
if (!is_path_reachable(m, m->mnt.mnt_root, &root) &&
!ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN))

if (!is_umount_ns(ns) && !is_path_reachable(m, m->mnt.mnt_root, &root))
return -EPERM;

if (!ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN))
return -EPERM;

err = security_sb_statfs(s->mnt->mnt_root);
Expand Down