1 /* 32-bit compatibility syscall for 64-bit systems 2 * 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/syscalls.h> 13 #include <linux/keyctl.h> 14 #include <linux/compat.h> 15 #include <linux/slab.h> 16 #include "internal.h" 17 18 /* 19 * Instantiate a key with the specified compatibility multipart payload and 20 * link the key into the destination keyring if one is given. 21 * 22 * The caller must have the appropriate instantiation permit set for this to 23 * work (see keyctl_assume_authority). No other permissions are required. 24 * 25 * If successful, 0 will be returned. 26 */ 27 static long compat_keyctl_instantiate_key_iov( 28 key_serial_t id, 29 const struct compat_iovec __user *_payload_iov, 30 unsigned ioc, 31 key_serial_t ringid) 32 { 33 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; 34 struct iov_iter from; 35 long ret; 36 37 if (!_payload_iov) 38 ioc = 0; 39 40 ret = compat_import_iovec(WRITE, _payload_iov, ioc, 41 ARRAY_SIZE(iovstack), &iov, 42 &from); 43 if (ret < 0) 44 return ret; 45 46 ret = keyctl_instantiate_key_common(id, &from, ringid); 47 kfree(iov); 48 return ret; 49 } 50 51 /* 52 * The key control system call, 32-bit compatibility version for 64-bit archs 53 * 54 * This should only be called if the 64-bit arch uses weird pointers in 32-bit 55 * mode or doesn't guarantee that the top 32-bits of the argument registers on 56 * taking a 32-bit syscall are zero. If you can, you should call sys_keyctl() 57 * directly. 58 */ 59 COMPAT_SYSCALL_DEFINE5(keyctl, u32, option, 60 u32, arg2, u32, arg3, u32, arg4, u32, arg5) 61 { 62 switch (option) { 63 case KEYCTL_GET_KEYRING_ID: 64 return keyctl_get_keyring_ID(arg2, arg3); 65 66 case KEYCTL_JOIN_SESSION_KEYRING: 67 return keyctl_join_session_keyring(compat_ptr(arg2)); 68 69 case KEYCTL_UPDATE: 70 return keyctl_update_key(arg2, compat_ptr(arg3), arg4); 71 72 case KEYCTL_REVOKE: 73 return keyctl_revoke_key(arg2); 74 75 case KEYCTL_DESCRIBE: 76 return keyctl_describe_key(arg2, compat_ptr(arg3), arg4); 77 78 case KEYCTL_CLEAR: 79 return keyctl_keyring_clear(arg2); 80 81 case KEYCTL_LINK: 82 return keyctl_keyring_link(arg2, arg3); 83 84 case KEYCTL_UNLINK: 85 return keyctl_keyring_unlink(arg2, arg3); 86 87 case KEYCTL_SEARCH: 88 return keyctl_keyring_search(arg2, compat_ptr(arg3), 89 compat_ptr(arg4), arg5); 90 91 case KEYCTL_READ: 92 return keyctl_read_key(arg2, compat_ptr(arg3), arg4); 93 94 case KEYCTL_CHOWN: 95 return keyctl_chown_key(arg2, arg3, arg4); 96 97 case KEYCTL_SETPERM: 98 return keyctl_setperm_key(arg2, arg3); 99 100 case KEYCTL_INSTANTIATE: 101 return keyctl_instantiate_key(arg2, compat_ptr(arg3), arg4, 102 arg5); 103 104 case KEYCTL_NEGATE: 105 return keyctl_negate_key(arg2, arg3, arg4); 106 107 case KEYCTL_SET_REQKEY_KEYRING: 108 return keyctl_set_reqkey_keyring(arg2); 109 110 case KEYCTL_SET_TIMEOUT: 111 return keyctl_set_timeout(arg2, arg3); 112 113 case KEYCTL_ASSUME_AUTHORITY: 114 return keyctl_assume_authority(arg2); 115 116 case KEYCTL_GET_SECURITY: 117 return keyctl_get_security(arg2, compat_ptr(arg3), arg4); 118 119 case KEYCTL_SESSION_TO_PARENT: 120 return keyctl_session_to_parent(); 121 122 case KEYCTL_REJECT: 123 return keyctl_reject_key(arg2, arg3, arg4, arg5); 124 125 case KEYCTL_INSTANTIATE_IOV: 126 return compat_keyctl_instantiate_key_iov( 127 arg2, compat_ptr(arg3), arg4, arg5); 128 129 case KEYCTL_INVALIDATE: 130 return keyctl_invalidate_key(arg2); 131 132 case KEYCTL_GET_PERSISTENT: 133 return keyctl_get_persistent(arg2, arg3); 134 135 case KEYCTL_DH_COMPUTE: 136 return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3), 137 arg4, compat_ptr(arg5)); 138 139 default: 140 return -EOPNOTSUPP; 141 } 142 } 143