logo

bootstrap-initrd

Linux initrd to bootstrap from a small binary seed git clone https://hacktivis.me/git/bootstrap-initrd.git
commit: bb51173300fdadc544ad3d6f2039198899f17628
parent ca5de6e0f117c912ad2206bafcaca61084fad0c1
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Thu, 16 May 2024 06:26:59 +0200

Drop into a TTY instead of a rescueshell

Diffstat:

Agetty-stub.c81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minit.sh25+++++++++++++++++++++----
Mmake-root.sh1+
3 files changed, 103 insertions(+), 4 deletions(-)

diff --git a/getty-stub.c b/getty-stub.c @@ -0,0 +1,81 @@ +// bootstrap-initrd: Linux initrd to bootstrap from a small binary seed +// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +// SPDX-License-Identifier: MPL-2.0 + +#define _GNU_SOURCE // TIOCSCTTY, vhangup +#define _POSIX_C_SOURCE 200809L + +#include <stdio.h> // fprintf +#include <signal.h> +#include <unistd.h> // setsid, isatty +#include <errno.h> +#include <string.h> // strerror +#include <sys/ioctl.h> +#include <stdlib.h> // setenv +#include <fcntl.h> // open, O_RDWR + +int +main(int argc, char *argv[]) +{ + argc -= 1; + argv += 1; + + if(argc < 2) + { + fprintf(stderr, "Usage: getty tty cmd [args...]\n"); + return 1; + } + + signal(SIGHUP, SIG_IGN); + + setenv("TERM", "linux", 1); + + setsid(); + + char *tty = argv[0]; + argc -= 1; + argv += 1; + + int tty_fd = open(tty, O_RDWR); + if(tty_fd < 0) + { + fprintf(stderr, "getty: Failed opening TTY '%s': %s\n", tty, strerror(errno)); + return 1; + } + + if(ioctl(tty_fd, TIOCSCTTY, (void *)1) != 0) + { + fprintf(stderr, "getty: Couldn't set controlling TTY: %s\n", strerror(errno)); + return 1; + } + + vhangup(); + close(tty_fd); + + tty_fd = open(tty, O_RDWR); + if(tty_fd < 0) + { + fprintf(stderr, "getty: Failed opening TTY '%s': %s\n", tty, strerror(errno)); + return 1; + } + + if(dup2(tty_fd, 0) < 0) + { + fprintf(stderr, "getty: Failed setting TTY as stdin: %s\n", strerror(errno)); + return 1; + } + if(dup2(tty_fd, 1) < 0) + { + fprintf(stderr, "getty: Failed setting TTY as stdout: %s\n", strerror(errno)); + return 1; + } + if(dup2(tty_fd, 2) < 0) + { + fprintf(stderr, "getty: Failed setting TTY as stderr: %s\n", strerror(errno)); + return 1; + } + + signal(SIGHUP, SIG_DFL); + + return execvp(argv[0], argv); +} diff --git a/init.sh b/init.sh @@ -26,7 +26,7 @@ build_awk() { } build_stubs() { - for i in ls grep cp + for i in ls grep cp getty do $CC $CFLAGS -o "/bin/$i" "/${i}-stub.c" || die "Failed compiling $i stub" done @@ -187,6 +187,23 @@ mkdir -p /usr/share/cacert/ || die mv /cacert-*.pem /usr/share/cacert/cert.pem || die cat /proc/uptime -echo 'Done bootstrapping!' -cd / -rescueshell +echo 'Done bootstrapping! Press return to get a TTY' + +read _ + +cd + +if ! grep -q console= /proc/cmdline +then + getty "/dev/tty1" /bin/sh -l & +else + for arg in $(cat /proc/cmdline); do + case $arg in + console=*) + getty "/dev/${arg#console=}" /bin/sh -l & + ;; + esac + done +fi + +wait diff --git a/make-root.sh b/make-root.sh @@ -39,6 +39,7 @@ local_files=" ls-stub.c grep-stub.c cp-stub.c + getty-stub.c bootstrap-bash.sh bootstrap-make.sh bootstrap-xz.sh