From 48589b5d3957c27a5944e23fd770687adc078934 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Mon, 14 Sep 2009 17:40:23 -0400 Subject: [PATCH] Linux: Restore aklog -setpag functionality for kernel 2.6.32+ With kernel 2.6.32 it is now possible for a process to copy its session keyring to its parent through the use of the KEYCTL_SESSION_TO_PARENT function of the keyctl syscall. We can't use this easily from kernel space to cover all calls to VIOCSETTOK with the setpag flag - we'd need to make a syscall or have keyctl exported. Instead, a hook is added to ktc_SetToken to make it honour the AFS_SETTOK_SETPAG flag, which was ineffective with recent kernels. This should cover the most common cases (ex: aklog) where this is needed. The syscall is coded directly to avoid introducing a dependency on the keyutils library or header files which may not be installed everywhere. Reviewed-on: http://gerrit.openafs.org/463 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- acinclude.m4 | 1 + src/auth/ktc.c | 13 +++++++++++++ src/cf/linux-test4.m4 | 12 ++++++++++++ 3 files changed, 26 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 84423ec864..345317afa7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -934,6 +934,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_KERNEL_HLIST_UNHASHED LINUX_KEY_TYPE_H_EXISTS LINUX_EXPORTS_KEY_TYPE_KEYRING + LINUX_KEYS_HAVE_SESSION_TO_PARENT LINUX_NEED_RHCONFIG LINUX_RECALC_SIGPENDING_ARG_TYPE LINUX_SCHED_STRUCT_TASK_STRUCT_HAS_PARENT diff --git a/src/auth/ktc.c b/src/auth/ktc.c index 617c058c56..c2a39e8758 100644 --- a/src/auth/ktc.c +++ b/src/auth/ktc.c @@ -73,6 +73,11 @@ #endif /* defined(UKERNEL) */ +#if defined(LINUX_KEYRING_SUPPORT) && defined(HAVE_SESSION_TO_PARENT) +#include +#define KEYCTL_SESSION_TO_PARENT 18 +#endif + /* For malloc() */ #include #include "ktc.h" @@ -415,6 +420,14 @@ OldSetToken(struct ktc_principal *aserver, struct ktc_token *atoken, } #else /* NO_AFS_CLIENT */ code = PIOCTL(0, VIOCSETTOK, &iob, 0); +#if defined(LINUX_KEYRING_SUPPORT) && defined(HAVE_SESSION_TO_PARENT) + /* + * If we're using keyring based PAGs and the SESSION_TO_PARENT keyctl + * is available, use it to copy the session keyring to the parent process + */ + if (flags & AFS_SETTOK_SETPAG) + syscall(SYS_keyctl, KEYCTL_SESSION_TO_PARENT); +#endif #endif /* NO_AFS_CLIENT */ if (code) return KTC_PIOCTLFAIL; diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 866f7af04e..afc2442457 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -1264,3 +1264,15 @@ printk("%s", key_type_keyring.name); AC_DEFINE([EXPORTED_KEY_TYPE_KEYRING], 1, [define if key_type_keyring is exported]) fi]) +AC_DEFUN([LINUX_KEYS_HAVE_SESSION_TO_PARENT], [ + AC_MSG_CHECKING([for KEYCTL_SESSION_TO_PARENT]) + AC_CACHE_VAL([ac_cv_linux_have_session_to_parent], [ + AC_TRY_KBUILD( +[ #include ], +[ int i = KEYCTL_SESSION_TO_PARENT;], + ac_cv_linux_have_session_to_parent=yes, + ac_cv_linux_have_session_to_parent=no)]) + AC_MSG_RESULT($ac_cv_linux_have_session_to_parent) + if test "x$ac_cv_linux_have_session_to_parent" = "xyes"; then + AC_DEFINE([HAVE_SESSION_TO_PARENT], 1, [define if keyctl has the KEYCTL_SESSION_TO_PARENT function]) + fi])