namespace-util: return recognizable error if namespace_open_by_type() fails because ns type not supported
This makes sure the the codepath that derives an nsfd from a pid works the same for the pidfd case and the non-pidfd case: if we can verify that /proc/ is mounted but the /proc/$PID/ns/ files are missing, we can assume the ns type is not supported by the kernel. Hence return the same ENOPKG error in this case as we already do in the pidfd ioctl based codepath.
This commit is contained in:
@@ -71,13 +71,19 @@ static int pidref_namespace_open_by_type_internal(const PidRef *pidref, Namespac
|
||||
const char *p;
|
||||
|
||||
p = pid_namespace_path(pidref->pid, type);
|
||||
nsfd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC);
|
||||
if (nsfd < 0) {
|
||||
if (errno == ENOENT && proc_mounted() == 0)
|
||||
return -ENOSYS;
|
||||
nsfd = RET_NERRNO(open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC));
|
||||
if (nsfd == -ENOENT) {
|
||||
r = proc_mounted();
|
||||
if (r == 0)
|
||||
return -ENOSYS; /* /proc/ is not available or not set up properly, we're most likely
|
||||
in some chroot environment. */
|
||||
if (r > 0)
|
||||
return -ENOPKG; /* If /proc/ is definitely around then this means the namespace type is not supported */
|
||||
|
||||
return -errno;
|
||||
/* can't determine? then propagate original error */
|
||||
}
|
||||
if (nsfd < 0)
|
||||
return nsfd;
|
||||
|
||||
if (!need_verify) { /* Otherwise we verify on our own */
|
||||
r = pidref_verify(pidref);
|
||||
@@ -143,7 +149,7 @@ int pidref_namespace_open(
|
||||
|
||||
if (ret_userns_fd) {
|
||||
userns_fd = pidref_namespace_open_by_type_internal(pidref, NAMESPACE_USER, &need_verify);
|
||||
if (userns_fd < 0 && !IN_SET(userns_fd, -ENOENT, -ENOPKG))
|
||||
if (userns_fd < 0 && userns_fd != -ENOPKG)
|
||||
return userns_fd;
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ TEST(fd_is_namespace) {
|
||||
ASSERT_OK_ZERO(fd_is_namespace(STDERR_FILENO, NAMESPACE_NET));
|
||||
|
||||
fd = namespace_open_by_type(NAMESPACE_MOUNT);
|
||||
if (IN_SET(fd, -ENOSYS, -ENOENT)) {
|
||||
if (IN_SET(fd, -ENOSYS, -ENOPKG)) {
|
||||
log_notice("Path %s not found, skipping test", "/proc/self/ns/mnt");
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user