Mount root and exec GNU bash.
authorThadeu Lima de Souza Cascardo <cascardo@cascardo.eti.br>
Thu, 20 Oct 2016 10:02:53 +0000 (10:02 +0000)
committerThadeu Lima de Souza Cascardo <cascardo@cascardo.eti.br>
Thu, 20 Oct 2016 10:02:53 +0000 (10:02 +0000)
Mounts a specific partition as root, chroots, then execs GNU bash.

Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@cascardo.eti.br>
main.c

diff --git a/main.c b/main.c
index f370220..b910217 100644 (file)
--- a/main.c
+++ b/main.c
 #include <stdlib.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include <sys/mman.h>
+#include <sys/mount.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
 #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;
 }