mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
sysctl: restore sysctls for correct namespaces
When we don't use userns, __userns_sysctl_op is called
in context of the current process. A mount namespaces is restored
the last one, so when we restore namespaces, we see /proc from the
host pid namespace. In this case we can't use virtual pid to access
/proc/pid.
Let's open /proc/self/ns and use this descriptor to switch namespaces.
Cc: Tycho Andersen <tycho.andersen@canonical.com>
Fixes: f79f4546cf
("sysctl: move sysctl calls to usernsd")
Signed-off-by: Andrew Vagin <avagin@openvz.org>
Acked-by: Tycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
23573119bd
commit
a1457a7b73
14
sysctl.c
14
sysctl.c
@@ -192,7 +192,7 @@ static int do_sysctl_op(int fd, struct sysctl_req *req, int op)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __userns_sysctl_op(void *arg, int unused, pid_t pid)
|
static int __userns_sysctl_op(void *arg, int proc_fd, pid_t pid)
|
||||||
{
|
{
|
||||||
int fd, ret = -1, dir, i, status, *fds = NULL;
|
int fd, ret = -1, dir, i, status, *fds = NULL;
|
||||||
struct sysctl_userns_req *userns_req = arg;
|
struct sysctl_userns_req *userns_req = arg;
|
||||||
@@ -288,7 +288,7 @@ static int __userns_sysctl_op(void *arg, int unused, pid_t pid)
|
|||||||
const char *nsname = ns_to_string(userns_req->ns);
|
const char *nsname = ns_to_string(userns_req->ns);
|
||||||
|
|
||||||
BUG_ON(!nsname);
|
BUG_ON(!nsname);
|
||||||
nsfd = open_proc(pid, "ns/%s", nsname);
|
nsfd = openat(proc_fd, nsname, O_RDONLY);
|
||||||
if (nsfd < 0) {
|
if (nsfd < 0) {
|
||||||
pr_perror("failed to open pid %d's ns %s", pid, nsname);
|
pr_perror("failed to open pid %d's ns %s", pid, nsname);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -382,7 +382,7 @@ out:
|
|||||||
|
|
||||||
int sysctl_op(struct sysctl_req *req, size_t nr_req, int op, unsigned int ns)
|
int sysctl_op(struct sysctl_req *req, size_t nr_req, int op, unsigned int ns)
|
||||||
{
|
{
|
||||||
int i;
|
int i, fd, ret;
|
||||||
struct sysctl_userns_req *userns_req;
|
struct sysctl_userns_req *userns_req;
|
||||||
struct sysctl_req *cur;
|
struct sysctl_req *cur;
|
||||||
|
|
||||||
@@ -453,5 +453,11 @@ int sysctl_op(struct sysctl_req *req, size_t nr_req, int op, unsigned int ns)
|
|||||||
cur = (struct sysctl_req *) (((char *) cur) + total_len);
|
cur = (struct sysctl_req *) (((char *) cur) + total_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return userns_call(__userns_sysctl_op, UNS_ASYNC, userns_req, MAX_UNSFD_MSG_SIZE, -1);
|
fd = open_proc(PROC_SELF, "ns");
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = userns_call(__userns_sysctl_op, UNS_ASYNC, userns_req, MAX_UNSFD_MSG_SIZE, fd);
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user