Matthew Garrett
2019-Apr-18 19:12 UTC
[klibc] [PATCH] 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> --- 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)) -- 2.21.0.392.gf8f6787159e-goog
Maybe Matching Threads
- [klibc:master] run-init: Allow the initramfs to be persisted across root changes
- [PATCH] Allow the initramfs to be persisted across root changes
- [klibc:master] run-init: Add dry-run mode
- [PATCH klibc] run-init: Add dry-run mode
- [PATCH] run-init: add drop_capabilities support