diff options
| -rw-r--r-- | arch/ppc/kernel/misc.S | 3 | ||||
| -rw-r--r-- | arch/ppc64/Kconfig | 5 | ||||
| -rw-r--r-- | arch/ppc64/kernel/misc.S | 6 | ||||
| -rw-r--r-- | arch/ppc64/kernel/sys_ppc32.c | 18 | ||||
| -rw-r--r-- | include/asm-ppc/unistd.h | 5 | ||||
| -rw-r--r-- | include/asm-ppc64/unistd.h | 5 | ||||
| -rw-r--r-- | include/linux/compat.h | 2 | ||||
| -rw-r--r-- | security/keys/Makefile | 1 | ||||
| -rw-r--r-- | security/keys/compat.c | 78 | ||||
| -rw-r--r-- | security/keys/internal.h | 20 | ||||
| -rw-r--r-- | security/keys/keyctl.c | 54 |
11 files changed, 166 insertions, 31 deletions
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 7141d7ecdafd..2e3a07675a10 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1447,3 +1447,6 @@ _GLOBAL(sys_call_table) .long sys_mq_notify .long sys_mq_getsetattr .long sys_ni_syscall /* 268 reserved for sys_kexec_load */ + .long sys_add_key + .long sys_request_key /* 270 */ + .long sys_keyctl diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index aeab781b58bd..6aef1b6ec4c5 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -376,6 +376,11 @@ source "arch/ppc64/Kconfig.debug" source "security/Kconfig" +config KEYS_COMPAT + bool + depends on COMPAT && KEYS + default y + source "crypto/Kconfig" source "lib/Kconfig" diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index e43d02098fdc..a422c7146644 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -963,6 +963,9 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_mq_notify .llong .compat_sys_mq_getsetattr .llong .sys_ni_syscall /* 268 reserved for sys_kexec_load */ + .llong .sys32_add_key + .llong .sys32_request_key + .llong .compat_keyctl .balign 8 _GLOBAL(sys_call_table) @@ -1235,3 +1238,6 @@ _GLOBAL(sys_call_table) .llong .sys_mq_notify .llong .sys_mq_getsetattr .llong .sys_ni_syscall /* 268 reserved for sys_kexec_load */ + .llong .sys_add_key + .llong .sys_request_key /* 270 */ + .llong .sys_keyctl diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 6a514b3d977c..2ff7af2c9d80 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -1328,3 +1328,21 @@ long ppc32_timer_create(clockid_t clock, return err; } + +asmlinkage long sys32_add_key(const char __user *_type, + const char __user *_description, + const void __user *_payload, + u32 plen, + u32 ringid) +{ + return sys_add_key(_type, _description, _payload, plen, ringid); +} + +asmlinkage long sys32_request_key(const char __user *_type, + const char __user *_description, + const char __user *_callout_info, + u32 destringid) +{ + return sys_request_key(_type, _description, _callout_info, destringid); +} + diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index 57fb02c6c9d3..63a16a4a8cbc 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h @@ -273,8 +273,11 @@ #define __NR_mq_notify 266 #define __NR_mq_getsetattr 267 #define __NR_kexec_load 268 +#define __NR_add_key 269 +#define __NR_request_key 270 +#define __NR_keyctl 271 -#define __NR_syscalls 269 +#define __NR_syscalls 272 #define __NR(n) #n diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h index b2ac359c7658..7851d0c5868c 100644 --- a/include/asm-ppc64/unistd.h +++ b/include/asm-ppc64/unistd.h @@ -279,8 +279,11 @@ #define __NR_mq_notify 266 #define __NR_mq_getsetattr 267 #define __NR_kexec_load 268 +#define __NR_add_key 269 +#define __NR_request_key 270 +#define __NR_keyctl 271 -#define __NR_syscalls 269 +#define __NR_syscalls 272 #ifdef __KERNEL__ #define NR_syscalls __NR_syscalls #endif diff --git a/include/linux/compat.h b/include/linux/compat.h index e1e78bb971aa..98eda6dfe594 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -119,6 +119,8 @@ long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, long compat_sys_shmctl(int first, int second, void __user *uptr); long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, unsigned nsems, const struct compat_timespec __user *timeout); +asmlinkage long compat_keyctl(u32 option, + u32 arg2, u32 arg3, u32 arg4, u32 arg5); asmlinkage ssize_t compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsigned long vlen); diff --git a/security/keys/Makefile b/security/keys/Makefile index bd6500dbab0e..ddb495d65062 100644 --- a/security/keys/Makefile +++ b/security/keys/Makefile @@ -10,4 +10,5 @@ obj-y := \ user_defined.o \ request_key.o +obj-$(CONFIG_KEYS_COMPAT) += compat.o obj-$(CONFIG_PROC_FS) += proc.o diff --git a/security/keys/compat.c b/security/keys/compat.c new file mode 100644 index 000000000000..5f8c31a1c1c0 --- /dev/null +++ b/security/keys/compat.c @@ -0,0 +1,78 @@ +/* compat.c: 32-bit compatibility syscall for 64-bit systems + * + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * 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. + */ + +#include <linux/sched.h> +#include <linux/syscalls.h> +#include <linux/keyctl.h> +#include <linux/compat.h> +#include "internal.h" + +/*****************************************************************************/ +/* + * the key control system call, 32-bit compatibility version for 64-bit archs + * - this should only be called if the 64-bit arch uses weird pointers in + * 32-bit mode or doesn't guarantee that the top 32-bits of the argument + * registers on taking a 32-bit syscall are zero + * - if you can, you should call sys_keyctl directly + */ +asmlinkage long compat_keyctl(u32 option, + u32 arg2, u32 arg3, u32 arg4, u32 arg5) +{ + switch (option) { + case KEYCTL_GET_KEYRING_ID: + return keyctl_get_keyring_ID(arg2, arg3); + + case KEYCTL_JOIN_SESSION_KEYRING: + return keyctl_join_session_keyring(compat_ptr(arg3)); + + case KEYCTL_UPDATE: + return keyctl_update_key(arg2, compat_ptr(arg3), arg4); + + case KEYCTL_REVOKE: + return keyctl_revoke_key(arg2); + + case KEYCTL_DESCRIBE: + return keyctl_describe_key(arg2, compat_ptr(arg3), arg4); + + case KEYCTL_CLEAR: + return keyctl_keyring_clear(arg2); + + case KEYCTL_LINK: + return keyctl_keyring_link(arg2, arg3); + + case KEYCTL_UNLINK: + return keyctl_keyring_unlink(arg2, arg3); + + case KEYCTL_SEARCH: + return keyctl_keyring_search(arg2, compat_ptr(arg3), + compat_ptr(arg4), arg5); + + case KEYCTL_READ: + return keyctl_read_key(arg2, compat_ptr(arg3), arg4); + + case KEYCTL_CHOWN: + return keyctl_chown_key(arg2, arg3, arg4); + + case KEYCTL_SETPERM: + return keyctl_setperm_key(arg2, arg3); + + case KEYCTL_INSTANTIATE: + return keyctl_instantiate_key(arg2, compat_ptr(arg3), arg4, + arg5); + + case KEYCTL_NEGATE: + return keyctl_negate_key(arg2, arg3, arg4); + + default: + return -EOPNOTSUPP; + } + +} /* end compat_keyctl() */ diff --git a/security/keys/internal.h b/security/keys/internal.h index e68e0c7ee29e..75c2d154d568 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -81,6 +81,26 @@ extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); extern int install_thread_keyring(struct task_struct *tsk); +/* + * keyctl functions + */ +extern long keyctl_get_keyring_ID(key_serial_t, int); +extern long keyctl_join_session_keyring(const char __user *); +extern long keyctl_update_key(key_serial_t, const void __user *, size_t); +extern long keyctl_revoke_key(key_serial_t); +extern long keyctl_keyring_clear(key_serial_t); +extern long keyctl_keyring_link(key_serial_t, key_serial_t); +extern long keyctl_keyring_unlink(key_serial_t, key_serial_t); +extern long keyctl_describe_key(key_serial_t, char __user *, size_t); +extern long keyctl_keyring_search(key_serial_t, const char __user *, + const char __user *, key_serial_t); +extern long keyctl_read_key(key_serial_t, char __user *, size_t); +extern long keyctl_chown_key(key_serial_t, uid_t, gid_t); +extern long keyctl_setperm_key(key_serial_t, key_perm_t); +extern long keyctl_instantiate_key(key_serial_t, const void __user *, + size_t, key_serial_t); +extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); + /* * debugging key validation diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 2045b24615fd..4d95fdb75bce 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/syscalls.h> #include <linux/keyctl.h> #include <linux/fs.h> #include <linux/err.h> @@ -231,7 +232,7 @@ asmlinkage long sys_request_key(const char __user *_type, * - the keyring must have search permission to be found * - implements keyctl(KEYCTL_GET_KEYRING_ID) */ -static long keyctl_get_keyring_ID(key_serial_t id, int create) +long keyctl_get_keyring_ID(key_serial_t id, int create) { struct key *key; long ret; @@ -254,7 +255,7 @@ static long keyctl_get_keyring_ID(key_serial_t id, int create) * join the session keyring * - implements keyctl(KEYCTL_JOIN_SESSION_KEYRING) */ -static long keyctl_join_session_keyring(const char __user *_name) +long keyctl_join_session_keyring(const char __user *_name) { char *name; long nlen, ret; @@ -297,9 +298,9 @@ static long keyctl_join_session_keyring(const char __user *_name) * - the key must be writable * - implements keyctl(KEYCTL_UPDATE) */ -static long keyctl_update_key(key_serial_t id, - const void __user *_payload, - size_t plen) +long keyctl_update_key(key_serial_t id, + const void __user *_payload, + size_t plen) { struct key *key; void *payload; @@ -346,7 +347,7 @@ static long keyctl_update_key(key_serial_t id, * - the key must be writable * - implements keyctl(KEYCTL_REVOKE) */ -static long keyctl_revoke_key(key_serial_t id) +long keyctl_revoke_key(key_serial_t id) { struct key *key; long ret; @@ -372,7 +373,7 @@ static long keyctl_revoke_key(key_serial_t id) * - the keyring must be writable * - implements keyctl(KEYCTL_CLEAR) */ -static long keyctl_keyring_clear(key_serial_t ringid) +long keyctl_keyring_clear(key_serial_t ringid) { struct key *keyring; long ret; @@ -398,7 +399,7 @@ static long keyctl_keyring_clear(key_serial_t ringid) * - the key must be linkable * - implements keyctl(KEYCTL_LINK) */ -static long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) +long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) { struct key *keyring, *key; long ret; @@ -432,7 +433,7 @@ static long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) * - we don't need any permissions on the key * - implements keyctl(KEYCTL_UNLINK) */ -static long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) +long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) { struct key *keyring, *key; long ret; @@ -470,9 +471,9 @@ static long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) * type;uid;gid;perm;description<NUL> * - implements keyctl(KEYCTL_DESCRIBE) */ -static long keyctl_describe_key(key_serial_t keyid, - char __user *buffer, - size_t buflen) +long keyctl_describe_key(key_serial_t keyid, + char __user *buffer, + size_t buflen) { struct key *key; char *tmpbuf; @@ -532,10 +533,10 @@ static long keyctl_describe_key(key_serial_t keyid, * there's one specified * - implements keyctl(KEYCTL_SEARCH) */ -static long keyctl_keyring_search(key_serial_t ringid, - const char __user *_type, - const char __user *_description, - key_serial_t destringid) +long keyctl_keyring_search(key_serial_t ringid, + const char __user *_type, + const char __user *_description, + key_serial_t destringid) { struct key_type *ktype; struct key *keyring, *key, *dest; @@ -649,9 +650,7 @@ static int keyctl_read_key_same(const struct key *key, const void *target) * irrespective of how much we may have copied * - implements keyctl(KEYCTL_READ) */ -static long keyctl_read_key(key_serial_t keyid, - char __user *buffer, - size_t buflen) +long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) { struct key *key, *skey; long ret; @@ -711,7 +710,7 @@ static long keyctl_read_key(key_serial_t keyid, * - if the uid or gid is -1, then that parameter is not changed * - implements keyctl(KEYCTL_CHOWN) */ -static long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) +long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) { struct key *key; long ret; @@ -770,7 +769,7 @@ static long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) * - the keyring owned by the changer * - implements keyctl(KEYCTL_SETPERM) */ -static long keyctl_setperm_key(key_serial_t id, key_perm_t perm) +long keyctl_setperm_key(key_serial_t id, key_perm_t perm) { struct key *key; long ret; @@ -814,10 +813,10 @@ static long keyctl_setperm_key(key_serial_t id, key_perm_t perm) * instantiate the key with the specified payload, and, if one is given, link * the key into the keyring */ -static long keyctl_instantiate_key(key_serial_t id, - const void __user *_payload, - size_t plen, - key_serial_t ringid) +long keyctl_instantiate_key(key_serial_t id, + const void __user *_payload, + size_t plen, + key_serial_t ringid) { struct key *key, *keyring; void *payload; @@ -877,9 +876,7 @@ static long keyctl_instantiate_key(key_serial_t id, * negatively instantiate the key with the given timeout (in seconds), and, if * one is given, link the key into the keyring */ -static long keyctl_negate_key(key_serial_t id, - unsigned timeout, - key_serial_t ringid) +long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) { struct key *key, *keyring; long ret; @@ -916,7 +913,6 @@ static long keyctl_negate_key(key_serial_t id, /*****************************************************************************/ /* * the key control system call - * - currently invoked through prctl() */ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) |
