| 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 |
| |