commit:     fcb399f5a685f088b9f10d9d57e326ee78f9e6dd
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Nov 12 03:56:24 2018 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Sun Dec  2 15:17:39 2018 +0000
URL:        https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=fcb399f5

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 <AT> gentoo.org>
Closes: https://github.com/gentoo/sandbox/pull/1
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>

 libsandbox/libsandbox.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

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() */

Reply via email to