Compare commits
4 Commits
f84a91315a
...
42bfdbfb89
Author | SHA1 | Date |
---|---|---|
Yu Watanabe | 42bfdbfb89 | |
Yu Watanabe | 9f2f185c40 | |
Yu Watanabe | fbc90f199d | |
Yu Watanabe | 4eb7ca115d |
|
@ -47,6 +47,28 @@ static NamespaceType clone_flag_to_namespace_type(unsigned long clone_flag) {
|
||||||
return _NAMESPACE_TYPE_INVALID;
|
return _NAMESPACE_TYPE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pidref_namespace_open_by_type(const PidRef *pidref, NamespaceType type) {
|
||||||
|
assert(type >= 0);
|
||||||
|
assert(type < _NAMESPACE_TYPE_MAX);
|
||||||
|
|
||||||
|
/* Here, pidref can be NULL or unset, but cannot be remote. */
|
||||||
|
if (pidref_is_remote(pidref))
|
||||||
|
return -EREMOTE;
|
||||||
|
|
||||||
|
const char *p = pid_namespace_path(pidref ? pidref->pid : 0, type);
|
||||||
|
|
||||||
|
int fd = RET_NERRNO(open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC));
|
||||||
|
if (fd == -ENOENT && proc_mounted() == 0)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
/* Here, we do not call pidref_verify(). The caller should call it on success. */
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int namespace_open_by_type(NamespaceType type) {
|
||||||
|
return pidref_namespace_open_by_type(NULL, type);
|
||||||
|
}
|
||||||
|
|
||||||
int pidref_namespace_open(
|
int pidref_namespace_open(
|
||||||
const PidRef *pidref,
|
const PidRef *pidref,
|
||||||
int *ret_pidns_fd,
|
int *ret_pidns_fd,
|
||||||
|
@ -59,51 +81,47 @@ int pidref_namespace_open(
|
||||||
userns_fd = -EBADF, root_fd = -EBADF;
|
userns_fd = -EBADF, root_fd = -EBADF;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(pidref_is_set(pidref));
|
assert(pidref);
|
||||||
|
|
||||||
|
if (!pidref_is_set(pidref))
|
||||||
|
return -ESRCH;
|
||||||
|
|
||||||
|
if (pidref_is_remote(pidref))
|
||||||
|
return -EREMOTE;
|
||||||
|
|
||||||
if (ret_pidns_fd) {
|
if (ret_pidns_fd) {
|
||||||
const char *pidns;
|
pidns_fd = pidref_namespace_open_by_type(pidref, NAMESPACE_PID);
|
||||||
|
|
||||||
pidns = pid_namespace_path(pidref->pid, NAMESPACE_PID);
|
|
||||||
pidns_fd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
|
|
||||||
if (pidns_fd < 0)
|
if (pidns_fd < 0)
|
||||||
return -errno;
|
return pidns_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret_mntns_fd) {
|
if (ret_mntns_fd) {
|
||||||
const char *mntns;
|
mntns_fd = pidref_namespace_open_by_type(pidref, NAMESPACE_MOUNT);
|
||||||
|
|
||||||
mntns = pid_namespace_path(pidref->pid, NAMESPACE_MOUNT);
|
|
||||||
mntns_fd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
|
|
||||||
if (mntns_fd < 0)
|
if (mntns_fd < 0)
|
||||||
return -errno;
|
return mntns_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret_netns_fd) {
|
if (ret_netns_fd) {
|
||||||
const char *netns;
|
netns_fd = pidref_namespace_open_by_type(pidref, NAMESPACE_NET);
|
||||||
|
|
||||||
netns = pid_namespace_path(pidref->pid, NAMESPACE_NET);
|
|
||||||
netns_fd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
|
|
||||||
if (netns_fd < 0)
|
if (netns_fd < 0)
|
||||||
return -errno;
|
return netns_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret_userns_fd) {
|
if (ret_userns_fd) {
|
||||||
const char *userns;
|
userns_fd = pidref_namespace_open_by_type(pidref, NAMESPACE_USER);
|
||||||
|
if (userns_fd < 0 && userns_fd != -ENOENT)
|
||||||
userns = pid_namespace_path(pidref->pid, NAMESPACE_USER);
|
return userns_fd;
|
||||||
userns_fd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
|
|
||||||
if (userns_fd < 0 && errno != ENOENT)
|
|
||||||
return -errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret_root_fd) {
|
if (ret_root_fd) {
|
||||||
const char *root;
|
const char *root;
|
||||||
|
|
||||||
root = procfs_file_alloca(pidref->pid, "root");
|
root = procfs_file_alloca(pidref->pid, "root");
|
||||||
root_fd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
|
root_fd = RET_NERRNO(open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY));
|
||||||
|
if (root_fd == -ENOENT)
|
||||||
|
return proc_mounted() > 0 ? -ENOENT : -ENOSYS;
|
||||||
if (root_fd < 0)
|
if (root_fd < 0)
|
||||||
return -errno;
|
return root_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = pidref_verify(pidref);
|
r = pidref_verify(pidref);
|
||||||
|
@ -401,9 +419,25 @@ int netns_acquire(void) {
|
||||||
return TAKE_FD(netns_fd);
|
return TAKE_FD(netns_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pid_namespace_stat(pid_t pid, NamespaceType type, struct stat *ret) {
|
||||||
|
assert(type >= 0);
|
||||||
|
assert(type < _NAMESPACE_TYPE_MAX);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
const char *p = pid_namespace_path(pid, type);
|
||||||
|
if (stat(p, ret) < 0) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
return proc_mounted() == 0 ? -ENOSYS : -ENOENT;
|
||||||
|
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int in_same_namespace(pid_t pid1, pid_t pid2, NamespaceType type) {
|
int in_same_namespace(pid_t pid1, pid_t pid2, NamespaceType type) {
|
||||||
const char *ns_path;
|
|
||||||
struct stat ns_st1, ns_st2;
|
struct stat ns_st1, ns_st2;
|
||||||
|
int r;
|
||||||
|
|
||||||
if (pid1 == 0)
|
if (pid1 == 0)
|
||||||
pid1 = getpid_cached();
|
pid1 = getpid_cached();
|
||||||
|
@ -414,13 +448,13 @@ int in_same_namespace(pid_t pid1, pid_t pid2, NamespaceType type) {
|
||||||
if (pid1 == pid2)
|
if (pid1 == pid2)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ns_path = pid_namespace_path(pid1, type);
|
r = pid_namespace_stat(pid1, type, &ns_st1);
|
||||||
if (stat(ns_path, &ns_st1) < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return r;
|
||||||
|
|
||||||
ns_path = pid_namespace_path(pid2, type);
|
r = pid_namespace_stat(pid2, type, &ns_st2);
|
||||||
if (stat(ns_path, &ns_st2) < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return r;
|
||||||
|
|
||||||
return stat_inode_same(&ns_st1, &ns_st2);
|
return stat_inode_same(&ns_st1, &ns_st2);
|
||||||
}
|
}
|
||||||
|
@ -463,24 +497,8 @@ int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_r
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int namespace_open_by_type(NamespaceType type) {
|
|
||||||
const char *p;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
assert(type >= 0);
|
|
||||||
assert(type < _NAMESPACE_TYPE_MAX);
|
|
||||||
|
|
||||||
p = pid_namespace_path(0, type);
|
|
||||||
|
|
||||||
fd = RET_NERRNO(open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC));
|
|
||||||
if (fd == -ENOENT && proc_mounted() == 0)
|
|
||||||
return -ENOSYS;
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_our_namespace(int fd, NamespaceType request_type) {
|
int is_our_namespace(int fd, NamespaceType request_type) {
|
||||||
int clone_flag;
|
int r, clone_flag;
|
||||||
|
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
@ -499,13 +517,9 @@ int is_our_namespace(int fd, NamespaceType request_type) {
|
||||||
if (fstat(fd, &st_fd) < 0)
|
if (fstat(fd, &st_fd) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
const char *p = pid_namespace_path(0, found_type);
|
r = pid_namespace_stat(0, found_type, &st_ours);
|
||||||
if (stat(p, &st_ours) < 0) {
|
if (r < 0)
|
||||||
if (errno == ENOENT)
|
return r;
|
||||||
return proc_mounted() == 0 ? -ENOSYS : -ENOENT;
|
|
||||||
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stat_inode_same(&st_ours, &st_fd);
|
return stat_inode_same(&st_ours, &st_fd);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue