Commit 4b8ddb73 authored by David Howells's avatar David Howells Committed by Linus Torvalds

[PATCH] ppc/ppc64: hook up key management syscalls

The attached patch permits my key management stuff to be used on PPC, PPC64
and PPC on PPC64. Syscall numbers were allocated by Paul Mackerras.

I've updated my keyctl utility to work on PPC/PPC64 too:

	http://people.redhat.com/~dhowells/keys/keyctl.cSigned-Off-By: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4168f5a1
......@@ -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
......@@ -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"
......@@ -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
......@@ -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);
}
......@@ -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
......
......@@ -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
......
......@@ -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);
......
......@@ -10,4 +10,5 @@ obj-y := \
user_defined.o \
request_key.o
obj-$(CONFIG_KEYS_COMPAT) += compat.o
obj-$(CONFIG_PROC_FS) += proc.o
/* 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() */
......@@ -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
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment