From a5bb76b2db7b6093cc1f350d75c810d9fab6d993 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 20 Oct 2016 10:02:53 +0000 Subject: [PATCH] Mount root and exec GNU bash. Mounts a specific partition as root, chroots, then execs GNU bash. Signed-off-by: Thadeu Lima de Souza Cascardo --- main.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/main.c b/main.c index f370220..b910217 100644 --- a/main.c +++ b/main.c @@ -21,11 +21,12 @@ #include #include #include -#include +#include #include #include #include #include +#include #define PREFIX "/sys/class/android_usb/android0/" @@ -43,17 +44,61 @@ int do_read(char *fname, char *buffer, size_t len) int fd; int r; fd = open(fname, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "failed to open %s: %s\n", fname, + strerror(errno)); + return -1; + } r = read(fd, buffer, len); close(fd); return r; } -int main(int argc, char **argv) +int +do_mknod(char *path, char *name, int block, int wait) { + char *fullpath; + size_t len; int r; - int fd = -1; char dev[33]; int maj, min; + len = strlen(path) + strlen(name) + 6; + fullpath = malloc(len); + if (!fullpath) { + fprintf(stderr, "failed to allocate buffer\n"); + return -1; + } + snprintf(fullpath, len, "%s/%s/dev", path, name); + do { + r = do_read(fullpath, dev, sizeof(dev)); + if (r < 0 && !wait) { + fprintf(stderr, "failed to read %s: %s\n", fullpath, + strerror(errno)); + goto out; + } + } while (r < 0 && wait); + r = sscanf(dev, "%d:%d", &maj, &min); + if (r < 0) { + fprintf(stderr, "failed to read devno from %s\n", dev); + goto out; + } + snprintf(fullpath, len, "/dev/%s", name); + r = mknod(fullpath, 0666 | (block ? S_IFBLK : S_IFCHR), makedev(maj, min)); + if (r < 0) { + fprintf(stderr, "failed to mknod %s: %s\n", fullpath, + strerror(errno)); + } +out: + free(fullpath); + return r; +} + +int main(int argc, char **argv) +{ + int r; + int fd = -1; + int i; + char *args[] = { "bash", "-l", NULL }; r = devmount_setup(); if (r < 0) { fprintf(stderr, "failed to mount devtmpfs, proceeding anyway\n"); @@ -68,15 +113,34 @@ int main(int argc, char **argv) do_write(PREFIX "/f_acm/acm_transports", "tty"); do_write(PREFIX "/functions", "acm"); do_write(PREFIX "/enable", "1"); - while (do_read("/sys/class/tty/ttyGS0/dev", dev, sizeof(dev)) < 0) { - sleep(1); - } - sscanf(dev, "%d:%d", &maj, &min); - mknod("/dev/ttyGS0", 0666 | S_IFCHR, makedev(maj, min)); + do_mknod("/sys/class/tty", "ttyGS0", 0, 1); fd = open("/dev/ttyGS0", O_RDWR); - while (1) { + for (i = 0; i < 10; i++) { write(fd, "Hello World!\n", 13); sleep(1); } + write(fd, "G\n", 2); + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + printf("N\n"); + r = do_mknod("/sys/block/mmcblk1", "mmcblk1p3", 1, 1); + if (r < 0) { + fprintf(stderr, "Failed to create mmcblk1p3\n"); + } + printf("U\n"); + printf("Mounting root\n"); + r = mkdir("/root", 0755); + if (r) printf("failed mkdir\n"); + r = mount("/dev/mmcblk1p3", "/root", "ext4", MS_NOATIME, NULL); + if (r) printf("failed mount: %d\n", errno); + printf("Chroot and chdir\n"); + r = chdir("/root"); + if (r) printf("failed first chdir\n"); + r = chroot("/root"); + if (r) printf("failed chroot\n"); + r = chdir("/"); + if (r) printf("failed second chdir\n"); + execve("/bin/bash", args, NULL); return 0; } -- 2.20.1