Matthew Garrett
2019-Apr-18 19:06 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. --- 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
Matthew Garrett
2019-Apr-18 19:10 UTC
[klibc] [PATCH] Allow the initramfs to be persisted across root changes
Crap, sorry, sent the wrong version of this. Hang on, let me send a real patch. On Thu, Apr 18, 2019 at 12:06 PM Matthew Garrett <matthewgarrett at google.com> wrote:> > 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 >
Reasonably Related Threads
- [PATCH klibc] run-init: Add dry-run mode
- [PATCH] run-init: add drop_capabilities support
- [PATCH] Allow the initramfs to be persisted across root changes
- [klibc:master] run-init: Allow the initramfs to be persisted across root changes
- [klibc:master] run-init: Add dry-run mode