From 68648f8fe23dd30cffec1ec05e3de42e434e1f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sun, 2 Dec 2018 21:09:06 +0100 Subject: Update to working version Still way off from something usable by someone else but it already works for me. --- main.c | 103 ++++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 54 insertions(+), 49 deletions(-) (limited to 'main.c') diff --git a/main.c b/main.c index a20f6ff..7957be3 100644 --- a/main.c +++ b/main.c @@ -1,58 +1,63 @@ +/* uroot - User's root + * main.c Source file with main function + * + * Copyright (C) 2018 Karel Kočí + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ #define _GNU_SOURCE #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include "child.h" #include "utils.h" +#include "sigpipe.h" +#include "conf.h" -void sigint_handler(int sig) { } int main(int argc, char **argv) { - pid_t ppid = getpid(); - - if (!fork()) { - system(aprintf("newuidmap %d 0 %d 1 1 65537 65536", ppid, getuid())); - system(aprintf("newgidmap %d 0 %d 1 1 65537 65536", ppid, getgid())); - kill(ppid, SIGINT); - return 0; - } - - unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWPID); - - signal(SIGINT, sigint_handler); - pause(); - errno = 0; // Just clear error from pause() - - pid_t chpid = fork(); - if (chpid) { - int stat; - waitpid(chpid, &stat, 0); - return stat; - } - - // mount /sys and /proc - mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL); - assert_perror(errno); - mount("none", "/proc", NULL, MS_REC | MS_PRIVATE, NULL); - assert_perror(errno); - mount("none", "/sys", NULL, MS_REC | MS_PRIVATE, NULL); - assert_perror(errno); - mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL); - assert_perror(errno); - - // mount proc to root - // rbind mount dev and sys to root - - // TODO verify that all upper directories have +rx rights - // TODO chroot - execv("/bin/sh", NULL); + // TODO arguments parsing + + struct child_args chargs = (struct child_args) { + .ppid = getpid(), + .argc = argc, + .argv = argv, + .sigpipe = sigpipe_new() + }; + + uint8_t stack[STACK_SIZE]; + pid_t chpid = clone(child_main, stack + STACK_SIZE, + SIGCHLD | CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWPID, + &chargs); + +#define FAIL(MSG) do { fputs(MSG, stderr); kill(chpid, SIGKILL); return 1; } while (false); + if (new_map_id("uid", chpid, getuid())) + FAIL("Mapping of uid failed!\n"); + if (new_map_id("gid", chpid, getgid())) + FAIL("Mapping of gid failed!\n"); + + sigpipe_signal(chargs.sigpipe); + + int stat; + waitpid(chpid, &stat, 0); + if (WIFEXITED(stat)) + return WEXITSTATUS(stat); + else + return WIFSIGNALED(stat) || WCOREDUMP(stat); } -- cgit v1.2.3