[lxc-devel] usernsselfmap
Serge Hallyn
serge.hallyn at ubuntu.com
Thu Mar 7 03:53:08 UTC 2013
Quoting Eric W. Biederman (ebiederm at xmission.com):
...
> For what it's worth. If you are going to do a combined binary, and you
> are just going to worry about yourself. You don't have to fork to
> write /proc/self/uid_map with 0 $old_uid 1.
Well, shoot! I figured since we'd already unshared, our uid was 65534 /
-1, and there was no sensible value to insert. Just tried with the orig
uid and it works. Neato.
> I had originally hoped to do an upcall to validate other writes to
> /proc/self/uid_map but code was never solid and I went with what works
> now.
Right, I remember that. This isn't so bad in the end
#include <stdio.h>
#include <sched.h>
#include <linux/sched.h>
#include <stdlib.h>
#include <errno.h>
int writemaps(pid_t pid, int origuid, int origgid)
{
FILE *fout;
char path[1024];
int ret;
printf("starting from uid %d gid %d\n", origuid, origgid);
snprintf(path, 1024, "/proc/%d/uid_map", pid);
fout = fopen(path, "w");
ret = fprintf(fout, "0 %d 1\n", origuid);
if (ret < 0) {
perror("writing uidmap\n");
return -1;
}
ret = fclose(fout);
if (ret < 0) {
perror("closing uidmap\n");
return -1;
}
snprintf(path, 1024, "/proc/%d/gid_map", pid);
fout = fopen(path, "w");
ret = fprintf(fout, "0 %d 1\n", origgid);
if (ret < 0) {
perror("writing gidmap\n");
return -1;
}
ret = fclose(fout);
if (ret < 0) {
perror("closing gidmap\n");
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
char *args[] = { "/bin/bash", NULL };
int ret;
int origuid = getuid();
int origgid = getgid();
ret = unshare(CLONE_NEWUSER);
ret = writemaps(getpid(), origuid, origgid);
if (ret < 0) {
printf("Error writing maps\n");
exit(1);
}
if (ret < 0) {
perror("unshare");
exit(1);
}
ret = setgid(0);
if (ret < 0)
perror("setgid");
ret = setuid(0);
perror("setuid");
printf("execing bash (I am now %d %d)\n", getuid(), getgid());
execv(args[0], args);
}
More information about the lxc-devel
mailing list