diff options
author | Karel Kočí <cynerd@email.cz> | 2018-12-02 21:09:06 +0100 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2018-12-02 21:41:15 +0100 |
commit | 68648f8fe23dd30cffec1ec05e3de42e434e1f31 (patch) | |
tree | a7bda6afb61a8d9da4ab0aff7ac993e823661578 /main.c | |
parent | 5a7d5fa43536484508aad9d9553f64a33212311b (diff) | |
download | uroot-68648f8fe23dd30cffec1ec05e3de42e434e1f31.tar.gz uroot-68648f8fe23dd30cffec1ec05e3de42e434e1f31.tar.bz2 uroot-68648f8fe23dd30cffec1ec05e3de42e434e1f31.zip |
Update to working version
Still way off from something usable by someone else but it already works
for me.
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 103 |
1 files changed, 54 insertions, 49 deletions
@@ -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 <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <unistd.h> #include <sys/types.h> -#include <sched.h> -#include <errno.h> -#include <assert.h> -#include <string.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/mount.h> #include <sys/wait.h> +#include <sched.h> +#include <unistd.h> +#include <stdint.h> +#include <stdbool.h> +#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); } |