keyring-dont-use-syscall2-20060906
authorChas Williams <chas@cmf.nrl.navy.mil>
Wed, 6 Sep 2006 21:56:01 +0000 (21:56 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 6 Sep 2006 21:56:01 +0000 (21:56 +0000)
avoid not-really-portable-use of syscall2

src/afs/LINUX/osi_groups.c
src/afs/sysincludes.h
src/cf/linux-test4.m4

index 1409624..c4a0514 100644 (file)
@@ -189,16 +189,60 @@ __setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag,
 }
 
 #ifdef LINUX_KEYRING_SUPPORT
-#include <asm/unistd.h>
-#include <linux/keyctl.h>
+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);
 }
 
index ed7117b..3f72a32 100644 (file)
@@ -73,6 +73,9 @@
 #if defined(LINUX_KEYRING_SUPPORT)
 #include <linux/rwsem.h>
 #include <linux/key.h>
+#ifndef KEY_ALLOC_IN_QUOTA
+#define KEY_ALLOC_IN_QUOTA 1
+#endif
 #endif
 #endif
 /* Avoid conflicts with coda overloading AFS type namespace. Must precede
index 9c2e0df..5485b2f 100644 (file)
@@ -614,12 +614,8 @@ AC_DEFUN([LINUX_LINUX_KEYRING_SUPPORT], [
     AC_TRY_KBUILD(
 [#include <linux/rwsem.h>
 #include <linux/key.h>
-#include <linux/keyctl.h>
-#include <asm/unistd.h>
-static int errno;
-static inline _syscall2(long, keyctl, int, option, void*, arg2);],
+#include <linux/keyctl.h>],
 [#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"