From 6b78dfd86b358e469916fd72ac2f3640caa21a34 Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Wed, 6 Sep 2006 21:57:17 +0000 Subject: [PATCH] STABLE14-keyring-dont-use-syscall2-20060906 avoid not-really-portable-use of syscall2 (cherry picked from commit 3dc9bcb1289bb868a336e820d589b03246c36bce) --- src/afs/LINUX/osi_groups.c | 68 +++++++++++++++++++++++++++++++++----- src/afs/sysincludes.h | 3 ++ src/cf/linux-test4.m4 | 6 +--- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c index 1409624f78..c4a0514dd5 100644 --- a/src/afs/LINUX/osi_groups.c +++ b/src/afs/LINUX/osi_groups.c @@ -189,16 +189,60 @@ __setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag, } #ifdef LINUX_KEYRING_SUPPORT -#include -#include +static struct key_type *__key_type_keyring; -static int errno; -static inline _syscall2(long, keyctl, int, option, void*, arg2); - -static long -__join_session_keyring(char *name) +static int +install_session_keyring(struct task_struct *task, struct key *keyring) { - return keyctl(KEYCTL_JOIN_SESSION_KEYRING, name); + struct key *old; + char desc[20]; + unsigned long not_in_quota; + int code = -EINVAL; + + if (!__key_type_keyring) + return code; + + if (!keyring) { + + /* create an empty session keyring */ + not_in_quota = KEY_ALLOC_IN_QUOTA; + sprintf(desc, "_ses.%u", task->tgid); + +#ifdef KEY_ALLOC_NEEDS_STRUCT_TASK + keyring = key_alloc(__key_type_keyring, desc, + task->uid, task->gid, task, + (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, + not_in_quota); +#else + keyring = key_alloc(__key_type_keyring, desc, + task->uid, task->gid, + (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, + not_in_quota); +#endif + if (IS_ERR(keyring)) { + code = PTR_ERR(keyring); + goto out; + } + } + + code = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL); + if (code < 0) { + key_put(keyring); + goto out; + } + + /* install the keyring */ + spin_lock_irq(&task->sighand->siglock); + old = task->signal->session_keyring; + smp_wmb(); + task->signal->session_keyring = keyring; + spin_unlock_irq(&task->sighand->siglock); + + if (old) + key_put(old); + +out: + return code; } #endif /* LINUX_KEYRING_SUPPORT */ @@ -255,7 +299,7 @@ setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag, #ifdef LINUX_KEYRING_SUPPORT if (code == 0) { - (void) __join_session_keyring(NULL); + (void) install_session_keyring(current, NULL); if (current->signal->session_keyring) { struct key *key; @@ -520,6 +564,12 @@ struct key_type key_type_afs_pag = void osi_keyring_init(void) { + struct task_struct *p; + + p = find_task_by_pid(1); + if (p && p->user->session_keyring) + __key_type_keyring = p->user->session_keyring->type; + register_key_type(&key_type_afs_pag); } diff --git a/src/afs/sysincludes.h b/src/afs/sysincludes.h index 22fe7a684e..df31f0f534 100644 --- a/src/afs/sysincludes.h +++ b/src/afs/sysincludes.h @@ -73,6 +73,9 @@ #if defined(LINUX_KEYRING_SUPPORT) #include #include +#ifndef KEY_ALLOC_IN_QUOTA +#define KEY_ALLOC_IN_QUOTA 1 +#endif #endif #endif /* Avoid conflicts with coda overloading AFS type namespace. Must precede diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 9c2e0dfb85..5485b2f232 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -614,12 +614,8 @@ AC_DEFUN([LINUX_LINUX_KEYRING_SUPPORT], [ AC_TRY_KBUILD( [#include #include -#include -#include -static int errno; -static inline _syscall2(long, keyctl, int, option, void*, arg2);], +#include ], [#ifdef CONFIG_KEYS -keyctl(KEYCTL_JOIN_SESSION_KEYRING, NULL); request_key(NULL, NULL, NULL); #if !defined(KEY_POS_VIEW) || !defined(KEY_POS_SEARCH) #error "Your linux/key.h does not contain KEY_POS_VIEW or KEY_POS_SEARCH"