From 5a7d5fa43536484508aad9d9553f64a33212311b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Mon, 27 Aug 2018 16:46:12 +0200 Subject: Initial commit --- .gitignore | 17 +++++++++++++++++ Makefile.am | 2 ++ bootstrap | 5 +++++ configure.ac | 5 +++++ main.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.c | 19 +++++++++++++++++++ utils.h | 17 +++++++++++++++++ 7 files changed, 123 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile.am create mode 100755 bootstrap create mode 100644 configure.ac create mode 100644 main.c create mode 100644 utils.c create mode 100644 utils.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b0e9a62 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.* +!.gitignore + +Makefile.in +aclocal.m4 +compile +configure +depcomp +install-sh +missing +Makefile +config.log +config.status +*.cache + +*.o +uroot diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..a451a6d --- /dev/null +++ b/Makefile.am @@ -0,0 +1,2 @@ +bin_PROGRAMS = uroot +uroot_SOURCES = main.c utils.c diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..71f0ee2 --- /dev/null +++ b/bootstrap @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +aclocal +automake --foreign --add-missing +autoconf diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..084b6bd --- /dev/null +++ b/configure.ac @@ -0,0 +1,5 @@ +AC_INIT([uroot], [0.1], [cynerd@email.cz]) +AM_INIT_AUTOMAKE([-Wall]) +AC_PROG_CC +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/main.c b/main.c new file mode 100644 index 0000000..a20f6ff --- /dev/null +++ b/main.c @@ -0,0 +1,58 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.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); +} diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..04806dd --- /dev/null +++ b/utils.c @@ -0,0 +1,19 @@ +#include "utils.h" + +// Compute the size needed (including \0) to format given message +size_t printf_len(const char *msg, ...) { + va_list args; + va_start(args, msg); + size_t result = vsnprintf(NULL, 0, msg, args); + va_end(args); + return result + 1; +} + +// Like sprintf, but returs the string. Expects there's enough space. +char *printf_into(char *dst, const char *msg, ...) { + va_list args; + va_start(args, msg); + vsprintf(dst, msg, args); + va_end(args); + return dst; +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..9e5984d --- /dev/null +++ b/utils.h @@ -0,0 +1,17 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#define _GNU_SOURCE +#include +#include +#include + +// Compute the size needed (including \0) to format given message +size_t printf_len(const char *msg, ...) __attribute__((format(printf, 1, 2))); +// Like sprintf, but returs the string. Expects there's enough space. +char *printf_into(char *dst, const char *msg, ...) __attribute__((format(printf, 2, 3))); +// Like printf, but allocates the data on the stack with alloca and returns. It +// uses the arguments multiple times, so beware of side effects. +#define aprintf(...) printf_into(alloca(printf_len(__VA_ARGS__)), __VA_ARGS__) + +#endif /* _UTILS_H_ */ -- cgit v1.2.3