aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Garrett <matthewgarrett@google.com>2019-04-18 12:12:27 -0700
committerBen Hutchings <ben@decadent.org.uk>2019-04-20 17:11:34 +0100
commit603f1bb024a03d9c50a89e7256ae7814292baf06 (patch)
treec89858a2c2cea7d1b899b3d5a0e5bc0b0c9d32cd
parentd4853d030639cf3542ae39129c18b654d8d4f020 (diff)
downloadklibc-603f1bb024a03d9c50a89e7256ae7814292baf06.tar.gz
[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@google.com> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--usr/kinit/kinit.c2
-rw-r--r--usr/kinit/run-init/run-init.c14
-rw-r--r--usr/kinit/run-init/run-init.h3
-rw-r--r--usr/kinit/run-init/runinitlib.c14
4 files changed, 21 insertions, 12 deletions
diff --git a/usr/kinit/kinit.c b/usr/kinit/kinit.c
index de03c2d318b12..28d29534896f0 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 a14ce7cce25d7..6a4ad3e5f1277 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 02c34aa23b992..5240ce75a6538 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 74d7883f8e4d3..1c2e56a441bca 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))