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:
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