Quoting Eric W. Biederman (ebied...@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);
}

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to