Skip to content

Instantly share code, notes, and snippets.

@aszlig
Created February 10, 2015 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aszlig/d14a279b9f14759e5a69 to your computer and use it in GitHub Desktop.
Save aszlig/d14a279b9f14759e5a69 to your computer and use it in GitHub Desktop.
POC of sandboxing without nested user namespaces
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "poc";
buildInputs = [ libcap_ng ];
buildCommand = ''
gcc -Wall -lcap-ng -o "$out" "${./poc.c}"
'';
}
#define _GNU_SOURCE
#include <cap-ng.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int syncpipe[2];
void ls_cwd(void)
{
struct dirent *dentry;
DIR *dir;
char curdir[PATH_MAX];
getcwd(curdir, PATH_MAX);
printf("contents of %s:\n", curdir);
dir = opendir(curdir);
while ((dentry = readdir(dir)))
printf("\t%s\n", dentry->d_name);
closedir(dir);
}
int childfun(void *arg)
{
char dummy;
close(syncpipe[1]);
read(syncpipe[0], &dummy, 1);
printf("chroot with retval %d\n", chroot("tmpchroot"));
chdir("tmpchroot");
fputs("in child!\n", stdout);
creat("test", 0666);
capng_clear(CAPNG_SELECT_BOTH);
capng_apply(CAPNG_SELECT_BOTH);
ls_cwd();
/* try to break out */
for (dummy = 0; dummy < 100; ++dummy)
chdir("..");
printf("chroot with retval %d\n", chroot("."));
ls_cwd();
return 0;
}
int main(void)
{
int flags, mapfd, pid;
char map_path[PATH_MAX];
char buf[255];
static char stackey[1048576];
pipe(syncpipe);
flags = CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS;
mkdir("tmpchroot", 0777);
pid = clone(childfun, stackey + 1048576, flags | SIGCHLD, NULL);
snprintf(map_path, PATH_MAX, "/proc/%ld/uid_map", (long) pid);
snprintf(buf, 255, "0 %d 1", geteuid());
mapfd = open(map_path, O_RDWR);
write(mapfd, buf, strlen(buf));
close(mapfd);
close(syncpipe[1]);
waitpid(pid, NULL, 0);
unlink("tmpchroot/test");
rmdir("tmpchroot");
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment