Make key management use syscalls not prctls
David Howells
maintainerPATCH 1/1 Make key management use syscalls not prctls
The attached patch makes the key management patch use syscalls instead of prctls, though only the i386 arch is so furnished by this patch.
This patch creates three new syscalls: add_key(), request_key() and keyctl(), the last of which is provides all the other key and keyring manipulation operations that used to be prctls.
Doing this allows simplification of the interface... those calls that take a payload no longer look for the payload length in the first two bytes of the buffer but take it instead as a syscall argument.
http://people.redhat.com/~dhowells/keys/keyctl.c has been updated to match.
---
warthog>diffstat keys-syscalls-269rc1mm2.diff
Documentation/keys.txt | 146 ++++++----- arch/i386/kernel/entry.S | 5 include/asm-generic/errno.h | 2 include/asm-i386/unistd.h | 9 include/linux/key.h | 21 + include/linux/keyctl.h | 39 +++ include/linux/prctl.h | 26 -- kernel/sys.c | 14 - security/keys/keyctl.c | 531 +++++++++++++++++++++++-------------------- security/keys/process_keys.c | 80 ------ 10 files changed, 440 insertions(+), 433 deletions(-)
arch/i386/kernel/entry.S +4 -1
@@ -943,6 +943,9 @@ .long sys_vperfctr_unlink .long sys_vperfctr_iresume .long sys_vperfctr_read - .long sys_waitid + .long sys_waitid /* 290 */ + .long sys_add_key + .long sys_request_key + .long sys_keyctl syscall_table_size=(.-sys_call_table)
Documentation/keys.txt +76 -70
202 lines not on this page · raw message
include/asm-generic/errno.h +2 -0
@@ -101,4 +101,6 @@#define EKEYREVOKED 127/* Key has been revoked */ #define EKEYREJECTED 128/* Key was rejected by service */ +#define __ERRNO_LAST 128 +#endif
include/asm-i386/unistd.h +6 -3
@@ -296,14 +296,17 @@#define __NR_vperfctr_iresume (__NR_perfctr_info+4)#define __NR_vperfctr_read (__NR_perfctr_info+5)#define __NR_waitid 290 +#define __NR_add_key 291 +#define __NR_request_key 292 +#define __NR_keyctl 293 -#define NR_syscalls 291 +#define NR_syscalls 294 -/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */ +/* user-visible error numbers are in the range -1 - -128: see <asm-i386/errno.h> */ #define __syscall_return (type, res) \ do { \ - if ((unsigned long)(res) >= (unsigned long)(-125)) { \ + if ((unsigned long)(res) >= (unsigned long)(-(__ERRNO_LAST + 1))) { \ errno = -(res); \ res = -1; \ } \
include/linux/keyctl.h +39 -0
@@ -0,0 +1,39 @@ +/* keyctl.h: keyctl command IDs +* +* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. +* Written by David Howells ([email protected]) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +*/ + +#ifndef _LINUX_KEYCTL_H +#define _LINUX_KEYCTL_H + +/* special process keyring shortcut IDs */ +#define KEY_SPEC_THREAD_KEYRING -1/* - key ID for thread-specific keyring */ +#define KEY_SPEC_PROCESS_KEYRING -2/* - key ID for process-specific keyring */ +#define KEY_SPEC_SESSION_KEYRING -3/* - key ID for session-specific keyring */ +#define KEY_SPEC_USER_KEYRING -4/* - key ID for UID-specific keyring */ +#define KEY_SPEC_USER_SESSION_KEYRING -5/* - key ID for UID-session keyring */ +#define KEY_SPEC_GROUP_KEYRING -6/* - key ID for GID-specific keyring */ + +/* keyctl commands */ +#define KEYCTL_GET_KEYRING_ID 0/* ask for a keyring's ID */ +#define KEYCTL_JOIN_SESSION_KEYRING 1/* join or start named session keyring */ +#define KEYCTL_UPDATE 2/* update a key */ +#define KEYCTL_REVOKE 3/* revoke a key */ +#define KEYCTL_CHOWN 4/* set ownership of a key */ +#define KEYCTL_SETPERM 5/* set perms on a key */ +#define KEYCTL_DESCRIBE 6/* describe a key */ +#define KEYCTL_CLEAR 7/* clear contents of a keyring */ +#define KEYCTL_LINK 8/* link a key into a keyring */ +#define KEYCTL_UNLINK 9/* unlink a key from a keyring */ +#define KEYCTL_SEARCH 10/* search for a key in a keyring */ +#define KEYCTL_READ 11/* read a key or keyring's contents */ +#define KEYCTL_INSTANTIATE 12/* instantiate a partially constructed key */ +#define KEYCTL_NEGATE 13/* negate a partially constructed key */ + +#endif /* _LINUX_KEYCTL_H */
include/linux/key.h +15 -6
@@ -250,10 +250,19 @@extern int exec_keys (struct task_struct *tsk);extern void key_fsuid_changed (struct task_struct *tsk);extern void key_fsgid_changed (struct task_struct *tsk); -extern long get_process_keyring_ID (key_serial_t id,int create); -extern long join_session_keyring_user (const char __user *name); -asmlinkage long sys_keyctl (int option,unsigned long arg2,unsigned long arg3, +asmlinkage long sys_add_key (const char __user *_type, +const char __user *_description, +const void __user *_payload, +size_t plen, +key_serial_t destringid); + +asmlinkage long sys_request_key (const char __user *_type, +const char __user *_description, +const char __user *_callout_info, +key_serial_t destringid); + +asmlinkage long sys_keyctl (int cmd,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5);#else /* CONFIG_KEYS */
@@ -267,9 +276,9 @@#define exec_keys (t) do { } while(0)#define key_fsuid_changed (t) do { } while(0)#define key_fsgid_changed (t) do { } while(0) -#define get_process_keyring_ID (s,c) (-EINVAL) -#define join_session_keyring_user (n) (-EINVAL) -#define sys_keyctl (o,b,c,d,e) (-EINVAL) +#define sys_addkey (a,b,c,d,e) (-ENOSYS) +#define sys_request_key (a,b,c,d,e) (-ENOSYS) +#define sys_keyctl (a,b,c,d,e) (-ENOSYS)#endif /* CONFIG_KEYS */ #endif /* __KERNEL__ */
include/linux/prctl.h +0 -26
@@ -49,30 +49,4 @@# define PR_TIMING_TIMESTAMP 1/* Accurate timestamp based process timing */ -/* Manage a process's keyrings */ -#define PR_SPEC_THREAD_KEYRING -1/* - key ID for thread-specific keyring */ -#define PR_SPEC_PROCESS_KEYRING -2/* - key ID for process-specific keyring */ -#define PR_SPEC_SESSION_KEYRING -3/* - key ID for session-specific keyring */ -#define PR_SPEC_USER_KEYRING -4/* - key ID for UID-specific keyring */ -#define PR_SPEC_USER_SESSION_KEYRING -5/* - key ID for UID-session keyring */ -#define PR_SPEC_GROUP_KEYRING -6/* - key ID for GID-specific keyring */ - -#define PR_GET_KEYRING_ID 15/* ask for a keyring's ID */ -#define PR_JOIN_SESSION_KEYRING 16/* join or start named session keyring */ -#define KEYCTL_NEW 0x100/* create a key and add to specified keyring */ -#define KEYCTL_UPDATE 0x101/* update a key */ -#define KEYCTL_REVOKE 0x102/* revoke a key */ -#define KEYCTL_CHOWN 0x103/* set ownership of a key */ -#define KEYCTL_SETPERM 0x104/* set perms on a key */ -#define KEYCTL_DESCRIBE 0x105/* describe a key */ -#define KEYCTL_CLEAR 0x106/* clear contents of a keyring */ -#define KEYCTL_LINK 0x107/* link a key into a keyring */ -#define KEYCTL_UNLINK 0x108/* unlink a key from a keyring */ -#define KEYCTL_SEARCH 0x109/* search for a key in a keyring */ -#define KEYCTL_READ 0x10a/* read a key or keyring's contents */ -#define KEYCTL_REQUEST_KEY 0x10b/* request a key from the process's keyrings */ -#define KEYCTL_INSTANTIATE 0x10c/* instantiate a partially constructed key */ -#define KEYCTL_NEGATE 0x10d/* negate a partially constructed key */ -#define __KEYCTL_LAST 0x10d -#endif /* _LINUX_PRCTL_H */
kernel/sys.c +3 -11
@@ -279,6 +279,9 @@ cond_syscall(sys_get_mempolicy) cond_syscall(sys_set_mempolicy) cond_syscall(compat_get_mempolicy) +cond_syscall(sys_add_key) +cond_syscall(sys_request_key) +cond_syscall(sys_keyctl) /* arch-specific weak syscall entries */ cond_syscall(sys_pciconfig_read)
@@ -1783,17 +1786,6 @@ current->keep_capabilities = arg2;break ; -case PR_GET_KEYRING_ID : - error =get_process_keyring_ID ((key_serial_t ) arg2, arg3); -break ; -case PR_JOIN_SESSION_KEYRING : - error =join_session_keyring_user ((const char __user *) arg2); -break ; - - case KEYCTL_NEW ... __KEYCTL_LAST: - error =sys_keyctl (option, arg2, arg3, arg4, arg5); -break ; -default : error = -EINVAL ;break ;
security/keys/keyctl.c +288 -243
784 lines not on this page · raw message
security/keys/process_keys.c +7 -73
127 lines not on this page · raw message
Umm, sys_keyctl is one of those ioctl lookalikes that are an incredible pain for 32bit compat and we agreed to not add anymore.
David Howells
maintainerQuoted 3 lines
Umm,
sys_keyctlis one of those ioctl lookalikes that are an incredible pain for 32bit compat and we agreed to not add anymore.
Fixing up should be trivial in this case. It should just be a matter of clearing the top 32 bits of every 64-bit argument. There are no structs that need grabbing from userspace and fixing up.
David