From 6c165c171431a1563ffc2220b34b78509eb0336e Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Mon, 6 Nov 2023 16:06:22 +1100 Subject: [PATCH] mountinfo: linux: add a /proc/self/mountinfo fallback In very specific cases (that we hit in runc), it is possible to be running in a child pid namespace (where the Go process's pid is 1) but still have a host /proc. While this is not a problem with /proc/thread-self (since the process *is* in the host pid namespace), the /proc/self/task/ fallback doesn't work because gettid(2) returns the wrong thread-id for the host pid namespace. There isn't much we can do in this case other than use /proc/self, because the simple workarounds (grep NSpid /proc/self/task/*/status) aren't available in pre-3.17 kernels and any more complicated schemes (such as setting the signal mask to something unique and scanning for it) are unworkable for obvious reasons. Fixes: 12c61a3e3acb ("mountinfo: linux: use /proc/thread-self/mountinfo") Signed-off-by: Aleksa Sarai --- mountinfo/mountinfo_linux.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mountinfo/mountinfo_linux.go b/mountinfo/mountinfo_linux.go index ea91657..b32b5c9 100644 --- a/mountinfo/mountinfo_linux.go +++ b/mountinfo/mountinfo_linux.go @@ -156,6 +156,14 @@ func parseMountTable(filter FilterFunc) (_ []*Info, err error) { // /proc/thread-self/ so we need to manually construct // /proc/self/task// as a fallback. f, err = os.Open("/proc/self/task/" + strconv.Itoa(unix.Gettid()) + "/mountinfo") + if os.IsNotExist(err) { + // If /proc/self/task/... failed, it means that our active pid + // namespace doesn't match the pid namespace of the /proc mount. In + // this case we just have to make do with /proc/self, since there + // is no other way of figuring out our tid in a parent pid + // namespace on pre-3.17 kernels. + f, err = os.Open("/proc/self/mountinfo") + } } if err != nil { return nil, err