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 <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Marc Dionne 2009-09-14 17:40:23 -04:00 committed by Derrick Brashear
parent 1ea845ebc9
commit 48589b5d39
3 changed files with 26 additions and 0 deletions

View File

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

View File

@ -73,6 +73,11 @@
#endif /* defined(UKERNEL) */
#if defined(LINUX_KEYRING_SUPPORT) && defined(HAVE_SESSION_TO_PARENT)
#include <sys/syscall.h>
#define KEYCTL_SESSION_TO_PARENT 18
#endif
/* For malloc() */
#include <stdlib.h>
#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;

View File

@ -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 <linux/keyctl.h>],
[ 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])