1 |
commit: fcb399f5a685f088b9f10d9d57e326ee78f9e6dd |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Nov 12 03:56:24 2018 +0000 |
4 |
Commit: Michał Górny <mgorny <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Dec 2 15:17:39 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=fcb399f5 |
7 |
|
8 |
libsandbox: resolve_dirfd_path /proc/<pid> namespace safety |
9 |
|
10 |
If /proc was mounted by a process in a different pid namespace, |
11 |
getpid cannot be used create a valid /proc/<pid> path. Instead |
12 |
use sb_get_fd_dir() which works in any case. This implements |
13 |
option 3 of these choices: |
14 |
|
15 |
1) Always create a mount namespace when creating a pid namespace, |
16 |
and remount /proc so that /proc/<pid> entries are always consistent |
17 |
with the current pid namespace. |
18 |
|
19 |
2) Use readlink on /proc/self instead of getpid to determine the pid |
20 |
of self in the pid namespace of the /proc mount. |
21 |
|
22 |
3) Use /proc/self or /dev/fd directly. |
23 |
|
24 |
Bug: https://bugs.gentoo.org/670966 |
25 |
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> |
26 |
Closes: https://github.com/gentoo/sandbox/pull/1 |
27 |
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org> |
28 |
|
29 |
libsandbox/libsandbox.c | 9 ++++++++- |
30 |
1 file changed, 8 insertions(+), 1 deletion(-) |
31 |
|
32 |
diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c |
33 |
index 9ef13b1..e0c9d1a 100644 |
34 |
--- a/libsandbox/libsandbox.c |
35 |
+++ b/libsandbox/libsandbox.c |
36 |
@@ -125,7 +125,14 @@ int resolve_dirfd_path(int dirfd, const char *path, char *resolved_path, |
37 |
save_errno(); |
38 |
|
39 |
size_t at_len = resolved_path_len - 1 - 1 - (path ? strlen(path) : 0); |
40 |
- sprintf(resolved_path, "/proc/%i/fd/%i", trace_pid ? : getpid(), dirfd); |
41 |
+ if (trace_pid) |
42 |
+ sprintf(resolved_path, "/proc/%i/fd/%i", trace_pid, dirfd); |
43 |
+ else |
44 |
+ /* If /proc was mounted by a process in a different pid namespace, |
45 |
+ * getpid cannot be used to create a valid /proc/<pid> path. Instead |
46 |
+ * use sb_get_fd_dir() which works in any case. |
47 |
+ */ |
48 |
+ sprintf(resolved_path, "%s/%i", sb_get_fd_dir(), dirfd); |
49 |
ssize_t ret = readlink(resolved_path, resolved_path, at_len); |
50 |
if (ret == -1) { |
51 |
/* see comments at end of check_syscall() */ |