Skip to content

Instantly share code, notes, and snippets.

@wfrisch
Last active February 7, 2024 10:26
Show Gist options
  • Save wfrisch/f4179ff9630e0f5b0f353ee7ae7c18ac to your computer and use it in GitHub Desktop.
Save wfrisch/f4179ff9630e0f5b0f353ee7ae7c18ac to your computer and use it in GitHub Desktop.
join a container from C/C++
/* Example on how to join the namespaces of containerized process */
#include <iostream>
#include <cstdint>
#include <sched.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
using namespace std;
static int pidfd_open(pid_t pid, unsigned int flags)
{
return syscall(__NR_pidfd_open, pid, flags);
}
int main(int argc, char** argv)
{
if (argc != 2) {
std::cerr << "usage: " << argv[0] << " PID" << std::endl;
return 1;
}
pid_t pid = std::stoul(argv[1]);
int pidfd = pidfd_open(pid, 0);
if (pidfd == -1) {
perror("pidfd_open");
exit(EXIT_FAILURE);
}
pid_t my_pid = getpid();
int my_pidfd = pidfd_open(my_pid, 0);
if (my_pidfd == -1) {
perror("pidfd_open");
exit(EXIT_FAILURE);
}
printf("Joining namespaces of %ul\n", pid);
if (setns(pidfd, CLONE_NEWCGROUP | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUSER | CLONE_NEWUTS)) {
// joining the TIME namespace is prohibited for rootless podman containers
perror("setns");
exit(EXIT_FAILURE);
}
system("ps axfu");
// THIS DOES NOT WORK:
// printf("Rejoining original namespaces (my_pid=%ul)\n", my_pid);
// if (setns(my_pidfd, CLONE_NEWCGROUP | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUSER | CLONE_NEWUTS)) {
// perror("setns");
// exit(EXIT_FAILURE);
// }
close(pidfd);
return 0;
}
#include <iostream>
#include <cstdint>
#include <sched.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
using namespace std;
static int pidfd_open(pid_t pid, unsigned int flags)
{
return syscall(__NR_pidfd_open, pid, flags);
}
int main(int argc, char** argv)
{
if (argc != 2) {
std::cerr << "usage: " << argv[0] << " PID" << std::endl;
return 1;
}
pid_t pid = std::stoul(argv[1]);
int pidfd = pidfd_open(pid, 0);
if (pidfd == -1) {
perror("pidfd_open");
exit(EXIT_FAILURE);
}
pid_t my_pid = getpid();
int my_pidfd = pidfd_open(my_pid, 0);
if (my_pidfd == -1) {
perror("pidfd_open");
exit(EXIT_FAILURE);
}
printf("Joining namespaces of %ul\n", pid);
if (setns(pidfd, CLONE_NEWCGROUP | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUSER | CLONE_NEWUTS)) {
perror("setns");
exit(EXIT_FAILURE);
}
system("ps axfu");
// THIS DOES NOT WORK:
printf("Rejoining original namespaces (my_pid=%ul)\n", my_pid);
if (setns(my_pidfd, CLONE_NEWCGROUP | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWTIME | CLONE_NEWUSER | CLONE_NEWUTS)) {
perror("setns");
exit(EXIT_FAILURE);
}
close(pidfd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment