[klibc] [klibc:master] run-init: Allow the initramfs to be persisted across root changes

klibc-bot for Matthew Garrett matthewgarrett at google.com
Sun Apr 28 08:51:05 PDT 2019


Commit-ID:  603f1bb024a03d9c50a89e7256ae7814292baf06
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=603f1bb024a03d9c50a89e7256ae7814292baf06
Author:     Matthew Garrett <matthewgarrett at google.com>
AuthorDate: Thu, 18 Apr 2019 12:12:27 -0700
Committer:  Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sat, 20 Apr 2019 17:11:34 +0100

[klibc] run-init: Allow the initramfs to be persisted across root changes

systemd supports switching back to the initramfs during shutdown in
order to make it easier to clean up the root file system. This is
desirable in order to allow us to remove keys from RAM before rebooting,
making it harder to obtain confidential information by rebooting into an
environment that scrapes RAM contents.

Signed-off-by: Matthew Garrett <mjg59 at google.com>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>

---
 usr/kinit/kinit.c               |  2 +-
 usr/kinit/run-init/run-init.c   | 14 ++++++++++----
 usr/kinit/run-init/run-init.h   |  3 ++-
 usr/kinit/run-init/runinitlib.c | 14 ++++++++------
 4 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/usr/kinit/kinit.c b/usr/kinit/kinit.c
index de03c2d3..28d29534 100644
--- a/usr/kinit/kinit.c
+++ b/usr/kinit/kinit.c
@@ -305,7 +305,7 @@ int main(int argc, char *argv[])
 
 	errmsg = run_init("/root", "/dev/console",
 			  get_arg(cmdc, cmdv, "drop_capabilities="), false,
-			  init_path, init_argv);
+			  false, init_path, init_argv);
 
 	/* If run_init returned, something went bad */
 	fprintf(stderr, "%s: %s: %s\n", progname, errmsg, strerror(errno));
diff --git a/usr/kinit/run-init/run-init.c b/usr/kinit/run-init/run-init.c
index a14ce7cc..6a4ad3e5 100644
--- a/usr/kinit/run-init/run-init.c
+++ b/usr/kinit/run-init/run-init.c
@@ -26,7 +26,7 @@
  * ----------------------------------------------------------------------- */
 
 /*
- * Usage: exec run-init [-d caps] [-c /dev/console] [-n] /real-root /sbin/init "$@"
+ * Usage: exec run-init [-d caps] [-c /dev/console] [-n] [-p] /real-root /sbin/init "$@"
  *
  * This program should be called as the last thing in a shell script
  * acting as /init in an initramfs; it does the following:
@@ -38,6 +38,9 @@
  * 5. Opens /dev/console;
  * 6. Spawns the specified init program (with arguments.)
  *
+ * With the -p option, it skips step 1 in order to allow the initramfs to
+ * be persisted into the running system.
+ *
  * With the -n option, it skips steps 1, 2 and 6 and can be used to check
  * whether the given root and init are likely to work.
  */
@@ -55,7 +58,7 @@ static const char *program;
 static void __attribute__ ((noreturn)) usage(void)
 {
 	fprintf(stderr,
-		"Usage: exec %s [-d caps] [-c consoledev] [-n] /real-root /sbin/init [args]\n",
+		"Usage: exec %s [-d caps] [-c consoledev] [-n] [-p] /real-root /sbin/init [args]\n",
 		program);
 	exit(1);
 }
@@ -69,6 +72,7 @@ int main(int argc, char *argv[])
 	const char *error;
 	const char *drop_caps = NULL;
 	bool dry_run = false;
+	bool persist_initramfs = false;
 	char **initargs;
 
 	/* Variables... */
@@ -77,13 +81,15 @@ int main(int argc, char *argv[])
 	/* Parse the command line */
 	program = argv[0];
 
-	while ((o = getopt(argc, argv, "c:d:n")) != -1) {
+	while ((o = getopt(argc, argv, "c:d:pn")) != -1) {
 		if (o == 'c') {
 			console = optarg;
 		} else if (o == 'd') {
 			drop_caps = optarg;
 		} else if (o == 'n') {
 			dry_run = true;
+		} else if (o == 'p') {
+			persist_initramfs = true;
 		} else {
 			usage();
 		}
@@ -96,7 +102,7 @@ int main(int argc, char *argv[])
 	init = argv[optind + 1];
 	initargs = argv + optind + 1;
 
-	error = run_init(realroot, console, drop_caps, dry_run, init, initargs);
+	error = run_init(realroot, console, drop_caps, dry_run, persist_initramfs, init, initargs);
 
 	if (error) {
 		fprintf(stderr, "%s: %s: %s\n", program, error, strerror(errno));
diff --git a/usr/kinit/run-init/run-init.h b/usr/kinit/run-init/run-init.h
index 02c34aa2..5240ce75 100644
--- a/usr/kinit/run-init/run-init.h
+++ b/usr/kinit/run-init/run-init.h
@@ -32,6 +32,7 @@
 
 const char *run_init(const char *realroot, const char *console,
 		     const char *drop_caps, bool dry_run,
-		     const char *init, char **initargs);
+		     bool persist_initramfs, const char *init,
+		     char **initargs);
 
 #endif
diff --git a/usr/kinit/run-init/runinitlib.c b/usr/kinit/run-init/runinitlib.c
index 74d7883f..1c2e56a4 100644
--- a/usr/kinit/run-init/runinitlib.c
+++ b/usr/kinit/run-init/runinitlib.c
@@ -26,7 +26,7 @@
  * ----------------------------------------------------------------------- */
 
 /*
- * run_init(realroot, consoledev, drop_caps, init, initargs)
+ * run_init(realroot, consoledev, drop_caps, persist_initramfs, init, initargs)
  *
  * This function should be called as the last thing in kinit,
  * from initramfs, it does the following:
@@ -156,8 +156,8 @@ static int nuke(const char *what)
 }
 
 const char *run_init(const char *realroot, const char *console,
-		     const char *drop_caps, bool dry_run, const char *init,
-		     char **initargs)
+		     const char *drop_caps, bool dry_run,
+		     bool persist_initramfs, const char *init, char **initargs)
 {
 	struct stat rst, cst, ist;
 	struct statfs sfs;
@@ -187,9 +187,11 @@ const char *run_init(const char *realroot, const char *console,
 	/* Okay, I think we should be safe... */
 
 	if (!dry_run) {
-		/* Delete rootfs contents */
-		if (nuke_dir("/"))
-			return "nuking initramfs contents";
+		if (!persist_initramfs) {
+			/* Delete rootfs contents */
+			if (nuke_dir("/"))
+				return "nuking initramfs contents";
+		}
 
 		/* Overmount the root */
 		if (mount(".", "/", NULL, MS_MOVE, NULL))


More information about the klibc mailing list