[klibc] [PATCH] run-init: add drop_capabilities support

Kees Cook keescook at chromium.org
Thu May 3 19:04:51 PDT 2012


Building on the work in ff0a614bd724f6c4c6a5014a9955dc1bc028f336,
this moves the capability code down into the run-init library, so that
run-init can use it as well, via the new "-d" flag.

Signed-off-by: Kees Cook <kees at outflux.net>
---
 usr/kinit/Kbuild                |    3 +--
 usr/kinit/capabilities.h        |   10 ++++++++++
 usr/kinit/kinit.c               |    6 +++---
 usr/kinit/run-init/Kbuild       |    9 +++++++--
 usr/kinit/run-init/run-init.c   |   12 ++++++++----
 usr/kinit/run-init/run-init.h   |    2 +-
 usr/kinit/run-init/runinitlib.c |   11 +++++++++--
 7 files changed, 39 insertions(+), 14 deletions(-)
 create mode 100644 usr/kinit/capabilities.h

diff --git a/usr/kinit/Kbuild b/usr/kinit/Kbuild
index 8f6d08e..5320127 100644
--- a/usr/kinit/Kbuild
+++ b/usr/kinit/Kbuild
@@ -3,14 +3,13 @@
 #
 
 # library part of kinit. Is used by programs in sub-directories (resume et al)
-lib-y   := name_to_dev.o devname.o getarg.o
+lib-y   := name_to_dev.o devname.o getarg.o capabilities.o
 # use lib for kinit
 kinit-y  := lib.a
 
 kinit-y  += kinit.o do_mounts.o ramdisk_load.o initrd.o
 kinit-y  += getintfile.o readfile.o xpio.o
 kinit-y  += do_mounts_md.o do_mounts_mtd.o nfsroot.o
-kinit-y  += capabilities.o
 
 kinit-y  += ipconfig/
 kinit-y  += nfsmount/
diff --git a/usr/kinit/capabilities.h b/usr/kinit/capabilities.h
new file mode 100644
index 0000000..a32a66a
--- /dev/null
+++ b/usr/kinit/capabilities.h
@@ -0,0 +1,10 @@
+/*
+ * capabilities.h
+ */
+
+#ifndef KINIT_CAPABILITIES_H
+#define KINIT_CAPABILITIES_H
+
+int drop_capabilities(const char *caps);
+
+#endif						/* KINIT_CAPABILITIES_H */
diff --git a/usr/kinit/kinit.c b/usr/kinit/kinit.c
index 8ea0da5..523c92b 100644
--- a/usr/kinit/kinit.c
+++ b/usr/kinit/kinit.c
@@ -284,8 +284,6 @@ int main(int argc, char *argv[])
 	check_path("/root");
 	do_mounts(cmdc, cmdv);
 
-	drop_capabilities(get_arg(cmdc, cmdv, "drop_capabilities="));
-
 	if (mnt_procfs) {
 		umount2("/proc", 0);
 		mnt_procfs = 0;
@@ -305,7 +303,9 @@ int main(int argc, char *argv[])
 
 	init_argv[0] = strrchr(init_path, '/') + 1;
 
-	errmsg = run_init("/root", "/dev/console", init_path, init_argv);
+	errmsg = run_init("/root", "/dev/console",
+			  get_arg(cmdc, cmdv, "drop_capabilities="),
+			  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/Kbuild b/usr/kinit/run-init/Kbuild
index bf6e140..f7832b7 100644
--- a/usr/kinit/run-init/Kbuild
+++ b/usr/kinit/run-init/Kbuild
@@ -18,9 +18,14 @@ lib-y := $(objs)
 # personality(2) flag from getting set and passed to init).
 EXTRA_KLIBCLDFLAGS += -z noexecstack
 
+# Additional include paths files
+KLIBCCFLAGS += -I$(srctree)/$(src)/..
+
 # .o files used to built executables
-static/run-init-y := $(objs)
-shared/run-init-y := $(objs)
+static/run-init-y   := $(objs)
+static/run-init-lib := ../lib.a
+shared/run-init-y   := $(objs)
+shared/run-init-lib := ../lib.a
 
 # Cleaning
 clean-dirs := static shared
diff --git a/usr/kinit/run-init/run-init.c b/usr/kinit/run-init/run-init.c
index 0f150dd..2147d06 100644
--- a/usr/kinit/run-init/run-init.c
+++ b/usr/kinit/run-init/run-init.c
@@ -26,13 +26,14 @@
  * ----------------------------------------------------------------------- */
 
 /*
- * Usage: exec run-init [-c /dev/console] /real-root /sbin/init "$@"
+ * Usage: exec run-init [-d caps] [-c /dev/console] /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:
  *
  * - Delete all files in the initramfs;
  * - Remounts /real-root onto the root filesystem;
+ * - Drops comma-separated list of capabilities;
  * - Chroots;
  * - Opens /dev/console;
  * - Spawns the specified init program (with arguments.)
@@ -50,7 +51,7 @@ static const char *program;
 static void __attribute__ ((noreturn)) usage(void)
 {
 	fprintf(stderr,
-		"Usage: exec %s [-c consoledev] /real-root /sbin/init [args]\n",
+		"Usage: exec %s [-d caps] [-c consoledev] /real-root /sbin/init [args]\n",
 		program);
 	exit(1);
 }
@@ -62,6 +63,7 @@ int main(int argc, char *argv[])
 	const char *realroot;
 	const char *init;
 	const char *error;
+	const char *drop_caps = NULL;
 	char **initargs;
 
 	/* Variables... */
@@ -70,9 +72,11 @@ int main(int argc, char *argv[])
 	/* Parse the command line */
 	program = argv[0];
 
-	while ((o = getopt(argc, argv, "c:")) != -1) {
+	while ((o = getopt(argc, argv, "c:d:")) != -1) {
 		if (o == 'c') {
 			console = optarg;
+		} else if (o == 'd') {
+			drop_caps = optarg;
 		} else {
 			usage();
 		}
@@ -85,7 +89,7 @@ int main(int argc, char *argv[])
 	init = argv[optind + 1];
 	initargs = argv + optind + 1;
 
-	error = run_init(realroot, console, init, initargs);
+	error = run_init(realroot, console, drop_caps, init, initargs);
 
 	/* If run_init returns, something went wrong */
 	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 a95328e..da3136a 100644
--- a/usr/kinit/run-init/run-init.h
+++ b/usr/kinit/run-init/run-init.h
@@ -29,6 +29,6 @@
 #define RUN_INIT_H
 
 const char *run_init(const char *realroot, const char *console,
-		     const char *init, char **initargs);
+		     const char *drop_caps, const char *init, char **initargs);
 
 #endif
diff --git a/usr/kinit/run-init/runinitlib.c b/usr/kinit/run-init/runinitlib.c
index 8f1562f..fe856bd 100644
--- a/usr/kinit/run-init/runinitlib.c
+++ b/usr/kinit/run-init/runinitlib.c
@@ -26,7 +26,7 @@
  * ----------------------------------------------------------------------- */
 
 /*
- * run_init(consoledev, realroot, init, initargs)
+ * run_init(realroot, consoledev, drop_caps, init, initargs)
  *
  * This function should be called as the last thing in kinit,
  * from initramfs, it does the following:
@@ -34,6 +34,7 @@
  * - Delete all files in the initramfs;
  * - Remounts /real-root onto the root filesystem;
  * - Chroots;
+ * - Drops comma-separated list of capabilities;
  * - Opens /dev/console;
  * - Spawns the specified init program (with arguments.)
  *
@@ -53,6 +54,7 @@
 #include <sys/types.h>
 #include <sys/vfs.h>
 #include "run-init.h"
+#include "capabilities.h"
 
 /* Make it possible to compile on glibc by including constants that the
    always-behind shipped glibc headers may not include.  Classic example
@@ -154,7 +156,8 @@ static int nuke(const char *what)
 }
 
 const char *run_init(const char *realroot, const char *console,
-		     const char *init, char **initargs)
+		     const char *drop_caps, const char *init,
+		     char **initargs)
 {
 	struct stat rst, cst;
 	struct statfs sfs;
@@ -195,6 +198,10 @@ const char *run_init(const char *realroot, const char *console,
 	if (chroot(".") || chdir("/"))
 		return "chroot";
 
+	/* Drop capabilities */
+	if (drop_capabilities(drop_caps) < 0)
+		return "dropping capabilities";
+
 	/* Open /dev/console */
 	if ((confd = open(console, O_RDWR)) < 0)
 		return "opening console";
-- 
1.7.9.5


-- 
Kees Cook                                            @outflux.net


More information about the klibc mailing list