blob: 6843cad37e1c2e2f008d04a353d7e27785104987 [file] [log] [blame]
This patch adds dircrypto ring in the init session.
With this patch, all other processes will have access to the dircrypto ring.
When the key for decoding an encrypted ext4 directory is added, all other
processes will be able to read the decoded information, assuming they have access
rights to that directory.
Patch by Gwendal Grignou <gwendal@chromium.org>,
updated by Guenter Roeck <groeck@chromium.org>
diff --git a/configure.ac b/configure.ac
index 3adbd49..404c5ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,6 +34,37 @@ PKG_CHECK_MODULES([UDEV], [libudev >= 146], [have_udev=yes], [have_udev=no])
AM_CONDITIONAL([HAVE_UDEV], [test "$have_udev" = yes])
+AC_MSG_CHECKING([wether to add a keyring for ext4 crypto])
+AC_ARG_WITH(
+ [dircrypto-keyring],
+ [AS_HELP_STRING(
+ [--with-dircrypto-keyring],
+ [add crypto keyring for directory encryption])],
+ [],
+ [with_dircrypto_keyring=auto]
+)
+
+KEYUTILS_LIBS=""
+
+AS_IF(
+ [test "$with_dircrypto_keyring" != "no"],
+ [
+ AC_CHECK_HEADER([keyutils.h],
+ [AC_CHECK_LIB([keyutils], [keyctl_read], [have_keyutils="yes"])]
+ )
+ if test "$have_keyutils" != "yes"; then
+ if test "$with_dircrypto_keyring" = "yes"; then
+ AC_MSG_ERROR([The keyutils library (or developer files) was not found])
+ fi
+ else
+ KEYUTILS_LIBS="-lkeyutils"
+ AC_DEFINE([ADD_DIRCRYPTO_RING], 1, [Use keyutils and kernel keyring])
+ fi
+ ]
+)
+
+AC_SUBST(KEYUTILS_LIBS)
+
# Checks for header files.
AC_CHECK_HEADERS([valgrind/valgrind.h])
diff --git a/init/Makefile.am b/init/Makefile.am
index 91410b1..7069ffa 100644
--- a/init/Makefile.am
+++ b/init/Makefile.am
@@ -62,6 +62,7 @@ init_LDADD = \
$(NIH_DBUS_LIBS) \
$(DBUS_LIBS) \
$(SELINUX_LIBS) \
+ $(KEYUTILS_LIBS) \
-lrt
diff --git a/init/main.c b/init/main.c
index 5e74f33..125239c 100644
--- a/init/main.c
+++ b/init/main.c
@@ -43,6 +43,10 @@
#include <syslog.h>
#include <unistd.h>
+#ifdef ADD_DIRCRYPTO_RING
+#include <keyutils.h>
+#endif
+
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
#include <selinux/restorecon.h>
@@ -309,6 +313,35 @@ main (int argc,
(int)getpid (), (int)getppid ());
#endif /* DEBUG */
+#ifdef ADD_DIRCRYPTO_RING
+ /*
+ * Set a keyring for the session to hold ext4 crypto keys.
+ * The session is at the root of all processes, so any users who wish
+ * to access a directory protected by ext4 crypto can access the key.
+ *
+ * Only set a session keyring if the kernel supports ext4 encryption.
+ */
+ if (!access("/sys/fs/ext4/features/encryption", F_OK)) {
+ key_serial_t keyring_id;
+
+ keyring_id = add_key ("keyring", "dircrypt", 0, 0,
+ KEY_SPEC_SESSION_KEYRING);
+ if (keyring_id == -1) {
+ nih_warn ("%s: %s",
+ _("Unable to create dircrypt keyring: %s"),
+ strerror (errno));
+ } else {
+ keyctl_setperm(keyring_id,
+ KEY_POS_VIEW | KEY_POS_SEARCH |
+ KEY_POS_LINK | KEY_POS_READ |
+ KEY_USR_ALL);
+ keyctl_setperm(KEY_SPEC_SESSION_KEYRING,
+ KEY_POS_VIEW | KEY_POS_SEARCH |
+ KEY_POS_LINK | KEY_POS_READ |
+ KEY_USR_ALL);
+ }
+ }
+#endif
/* Reset the signal state and install the signal handler for those
* signals we actually want to catch; this also sets those that
--
2.20.1