[klibc] [PATCH] Allow the initramfs to be persisted across root changes

Matthew Garrett matthewgarrett at google.com
Thu Apr 18 12:06:45 PDT 2019


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.
---
 debian/changelog                              |   4 +
 .../patches/run-init-allow-initramfs-persist  | 131 ++++++++++++++++++
 debian/patches/series                         |   1 +
 3 files changed, 136 insertions(+)
 create mode 100644 debian/patches/run-init-allow-initramfs-persist

diff --git a/debian/changelog b/debian/changelog
index 202f9d96..d658fa70 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -14,6 +14,10 @@ klibc (2.0.6-2) UNRELEASED; urgency=medium
   [ James Clarke ]
   * debian/control: Restrict m4 build dependency to just sparc
 
+  [ Matthew Garrett ]
+  * debian/patches/run-init-allow-initramfs-persist: Make it possible to
+    persist the initramfs into the running system
+
  -- Ben Hutchings <ben at decadent.org.uk>  Sat, 02 Feb 2019 00:14:28 +0000
 
 klibc (2.0.6-1) unstable; urgency=medium
diff --git a/debian/patches/run-init-allow-initramfs-persist b/debian/patches/run-init-allow-initramfs-persist
new file mode 100644
index 00000000..8ee76734
--- /dev/null
+++ b/debian/patches/run-init-allow-initramfs-persist
@@ -0,0 +1,131 @@
+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))
diff --git a/debian/patches/series b/debian/patches/series
index f13f4631..5be39790 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,3 @@
 resume-backward-compatibility-for-resume_offset.patch
 klibc-klcc-enable-stripping-even-if-config_debug_inf.patch
+run-init-allow-initramfs-persist
-- 
2.21.0.392.gf8f6787159e-goog



More information about the klibc mailing list