aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2018-11-11 19:56:24 -0800
committerMichał Górny <mgorny@gentoo.org>2018-12-02 16:17:39 +0100
commitfcb399f5a685f088b9f10d9d57e326ee78f9e6dd (patch)
treea169792fde9251ddedcc768af158266b7af39a18
parentlibsandbox: Remove meaningless/broken -nodefaultlibs (diff)
downloadsandbox-fcb399f5a685f088b9f10d9d57e326ee78f9e6dd.tar.gz
sandbox-fcb399f5a685f088b9f10d9d57e326ee78f9e6dd.tar.bz2
sandbox-fcb399f5a685f088b9f10d9d57e326ee78f9e6dd.zip
libsandbox: resolve_dirfd_path /proc/<pid> namespace safety
If /proc was mounted by a process in a different pid namespace, getpid cannot be used create a valid /proc/<pid> path. Instead use sb_get_fd_dir() which works in any case. This implements option 3 of these choices: 1) Always create a mount namespace when creating a pid namespace, and remount /proc so that /proc/<pid> entries are always consistent with the current pid namespace. 2) Use readlink on /proc/self instead of getpid to determine the pid of self in the pid namespace of the /proc mount. 3) Use /proc/self or /dev/fd directly. Bug: https://bugs.gentoo.org/670966 Signed-off-by: Zac Medico <zmedico@gentoo.org> Closes: https://github.com/gentoo/sandbox/pull/1 Signed-off-by: Michał Górny <mgorny@gentoo.org>
-rw-r--r--libsandbox/libsandbox.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c
index 9ef13b1..e0c9d1a 100644
--- a/libsandbox/libsandbox.c
+++ b/libsandbox/libsandbox.c
@@ -125,7 +125,14 @@ int resolve_dirfd_path(int dirfd, const char *path, char *resolved_path,
save_errno();
size_t at_len = resolved_path_len - 1 - 1 - (path ? strlen(path) : 0);
- sprintf(resolved_path, "/proc/%i/fd/%i", trace_pid ? : getpid(), dirfd);
+ if (trace_pid)
+ sprintf(resolved_path, "/proc/%i/fd/%i", trace_pid, dirfd);
+ else
+ /* If /proc was mounted by a process in a different pid namespace,
+ * getpid cannot be used to create a valid /proc/<pid> path. Instead
+ * use sb_get_fd_dir() which works in any case.
+ */
+ sprintf(resolved_path, "%s/%i", sb_get_fd_dir(), dirfd);
ssize_t ret = readlink(resolved_path, resolved_path, at_len);
if (ret == -1) {
/* see comments at end of check_syscall() */