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