]>
Commit | Line | Data |
---|---|---|
47f3b899 SI |
1 | From 37b0e20be5149d5dc049e2aed3e8b03589a6ffa0 Mon Sep 17 00:00:00 2001 |
2 | From: "Eric W. Biederman" <ebiederm@xmission.com> | |
3 | Date: Tue, 13 Nov 2018 07:44:38 +0000 | |
4 | Subject: [PATCH 11/11] mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED | |
5 | mounts | |
6 | ||
7 | BugLink: https://launchpad.net/bugs/1789161 | |
8 | ||
9 | Jonathan Calmels from NVIDIA reported that he's able to bypass the | |
10 | mount visibility security check in place in the Linux kernel by using | |
11 | a combination of the unbindable property along with the private mount | |
12 | propagation option to allow a unprivileged user to see a path which | |
13 | was purposefully hidden by the root user. | |
14 | ||
15 | Reproducer: | |
16 | # Hide a path to all users using a tmpfs | |
17 | root@castiana:~# mount -t tmpfs tmpfs /sys/devices/ | |
18 | root@castiana:~# | |
19 | ||
20 | # As an unprivileged user, unshare user namespace and mount namespace | |
21 | stgraber@castiana:~$ unshare -U -m -r | |
22 | ||
23 | # Confirm the path is still not accessible | |
24 | root@castiana:~# ls /sys/devices/ | |
25 | ||
26 | # Make /sys recursively unbindable and private | |
27 | root@castiana:~# mount --make-runbindable /sys | |
28 | root@castiana:~# mount --make-private /sys | |
29 | ||
30 | # Recursively bind-mount the rest of /sys over to /mnnt | |
31 | root@castiana:~# mount --rbind /sys/ /mnt | |
32 | ||
33 | # Access our hidden /sys/device as an unprivileged user | |
34 | root@castiana:~# ls /mnt/devices/ | |
35 | breakpoint cpu cstate_core cstate_pkg i915 intel_pt isa kprobe | |
36 | LNXSYSTM:00 msr pci0000:00 platform pnp0 power software system | |
37 | tracepoint uncore_arb uncore_cbox_0 uncore_cbox_1 uprobe virtual | |
38 | ||
39 | Solve this by teaching copy_tree to fail if a mount turns out to be | |
40 | both unbindable and locked. | |
41 | ||
42 | Cc: stable@vger.kernel.org | |
43 | Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users") | |
44 | Reported-by: Jonathan Calmels <jcalmels@nvidia.com> | |
45 | Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> | |
46 | (cherry picked from commit df7342b240185d58d3d9665c0bbf0a0f5570ec29) | |
47 | Signed-off-by: Tyler Hicks <tyhicks@canonical.com> | |
48 | Acked-by: Colin King <colin.king@canonical.com> | |
49 | Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> | |
50 | Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> | |
51 | --- | |
52 | fs/namespace.c | 10 ++++++++-- | |
53 | 1 file changed, 8 insertions(+), 2 deletions(-) | |
54 | ||
55 | diff --git a/fs/namespace.c b/fs/namespace.c | |
56 | index dcf107925150..91a3040f0cd0 100644 | |
57 | --- a/fs/namespace.c | |
58 | +++ b/fs/namespace.c | |
59 | @@ -1798,8 +1798,14 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, | |
60 | for (s = r; s; s = next_mnt(s, r)) { | |
61 | if (!(flag & CL_COPY_UNBINDABLE) && | |
62 | IS_MNT_UNBINDABLE(s)) { | |
63 | - s = skip_mnt_tree(s); | |
64 | - continue; | |
65 | + if (s->mnt.mnt_flags & MNT_LOCKED) { | |
66 | + /* Both unbindable and locked. */ | |
67 | + q = ERR_PTR(-EPERM); | |
68 | + goto out; | |
69 | + } else { | |
70 | + s = skip_mnt_tree(s); | |
71 | + continue; | |
72 | + } | |
73 | } | |
74 | if (!(flag & CL_COPY_MNT_NS_FILE) && | |
75 | is_mnt_ns_file(s->mnt.mnt_root)) { | |
76 | -- | |
77 | 2.11.0 | |
78 |