diff options
Diffstat (limited to 'security')
| -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 |
4 files changed, 124 insertions, 29 deletions
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) |
