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

Matthew Garrett mjg59 at google.com
Thu Apr 18 12:10:57 PDT 2019


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
>


More information about the klibc mailing list