I've to join a process to a new namespace, so i'm extracting the namespace fd's of a process, so that it can call setns on those fd's.
But the problem is all returned fd's are -1s.
I did this:
cout<<mnt<<"\n"; // prints /proc/4563/ns/mnt
int mnt_fd = open(mnt, O_RDONLY | O_CLOEXEC);
cout<<mnt_fd<<" \n"; // prints -1
cout<<net<<"\n"; // prints /proc/4563/ns/net
int net_fd = open(net, O_RDONLY | O_CLOEXEC);
cout<<net_fd<<" \n"; //prints -1
cout<<pid<<"\n"; // prints /proc/4563/ns/pid
int pid_fd = open(pid, O_RDONLY | O_CLOEXEC);
cout<<pid_fd<<" \n"; // prints -1
pid
, mnt
, net
are declared paths.
How can i resolve this ?
EDIT1: on printing stderror it says permission denied
On doing sudo chmod 755
on whole proc filesystem it prints operation not permitted
EDIT2: I was doing the mistake the of not compiling and running the executable with sudo. This time it can open the fds and returned fds are all positive. Similar to above i've opened other namespace fds too like usr_fd to join user namespace, ipc_fd to join ipc namespace and uts_fd to join uts namespace of the target process, but when doing setns
on userfd
it is givng error of Invalid argument
.
Below is the code i've written to join namespaces.
pid_t cpid = fork();
if(cpid == 0){
if (setns(pid_fd, 0) == -1) /* Join pid namespace */
cout<<"joining pid "<<strerror(errno);
if (setns(uts_fd, 0) == -1) /* Join uts namespace */
cout<<"joining uts "<<strerror(errno);
if (setns(ipc_fd, 0) == -1) /* Join pic namespace */
cout<<"joining ipc "<<strerror(errno);
if (setns(usr_fd, 0) == -1) /* Join usr namespace */
cout<<"joining usr "<<strerror(errno);
if (setns(net_fd, 0) == -1) /* Join net namespace */
cout<<"joining net "<<strerror(errno);
if (setns(mnt_fd, 0) == -1) /* Join mnt namespace */
cout<<"joining mnt "<<strerror(errno);
char *argv[] = { "sudo ./mycode",NULL };
execve(argv[0], argv, NULL);
}
I wanted the child process to execute the getcode program in that namespace but it is not doing so? If it is the wrong way to do this, then how can the child run a program in that namespace?
mycode.cpp
int main() {
printf("I am child process %d of parent %d\n", getpid(), getppid());
while (true) {
}
return 0;
}
EDIT3: However replacing below line:
char *argv[] = { "sudo ./mycode",NULL };
execve(argv[0], argv, NULL);
with this
char *argv[] = {"ps", NULL};
execvp(argv[0], &argv[0]);
works.