1/* 2 * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "defs.h" 29 30typedef int32_t key_serial_t; 31 32#include "xlat/key_spec.h" 33 34static void 35print_keyring_serial_number(key_serial_t id) 36{ 37 const char *str = xlookup(key_spec, id); 38 39 if (str) 40 tprints(str); 41 else 42 tprintf("%d", id); 43} 44 45SYS_FUNC(add_key) 46{ 47 /* type */ 48 printstr(tcp, tcp->u_arg[0], -1); 49 /* description */ 50 tprints(", "); 51 printstr(tcp, tcp->u_arg[1], -1); 52 /* payload */ 53 tprints(", "); 54 printstr(tcp, tcp->u_arg[2], tcp->u_arg[3]); 55 /* payload length */ 56 tprintf(", %lu, ", tcp->u_arg[3]); 57 /* keyring serial number */ 58 print_keyring_serial_number(tcp->u_arg[4]); 59 60 return RVAL_DECODED; 61} 62 63SYS_FUNC(request_key) 64{ 65 /* type */ 66 printstr(tcp, tcp->u_arg[0], -1); 67 /* description */ 68 tprints(", "); 69 printstr(tcp, tcp->u_arg[1], -1); 70 /* callout_info */ 71 tprints(", "); 72 printstr(tcp, tcp->u_arg[2], -1); 73 /* keyring serial number */ 74 tprints(", "); 75 print_keyring_serial_number(tcp->u_arg[3]); 76 77 return RVAL_DECODED; 78} 79 80static void 81keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create) 82{ 83 print_keyring_serial_number(id); 84 tprintf(", %d", create); 85} 86 87static void 88keyctl_update_key(struct tcb *tcp, key_serial_t id, long addr, long len) 89{ 90 print_keyring_serial_number(id); 91 tprints(", "); 92 printstr(tcp, addr, len); 93 tprintf(", %lu", len); 94} 95 96static void 97keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2) 98{ 99 print_keyring_serial_number(id1); 100 tprints(", "); 101 print_keyring_serial_number(id2); 102} 103 104static void 105keyctl_read_key(struct tcb *tcp, key_serial_t id, long addr, long len) 106{ 107 if (entering(tcp)) { 108 print_keyring_serial_number(id); 109 tprints(", "); 110 } else { 111 if (syserror(tcp)) 112 printaddr(addr); 113 else { 114 long rval = tcp->u_rval > len ? 115 len : (tcp->u_rval ? -1 : 0); 116 printstr(tcp, addr, rval); 117 } 118 tprintf(", %lu", len); 119 } 120} 121 122static void 123keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, long addr1, 124 long addr2, key_serial_t id2) 125{ 126 print_keyring_serial_number(id1); 127 tprints(", "); 128 printstr(tcp, addr1, -1); 129 tprints(", "); 130 printstr(tcp, addr2, -1); 131 tprints(", "); 132 print_keyring_serial_number(id2); 133} 134 135static void 136keyctl_chown_key(struct tcb *tcp, key_serial_t id, int user, int group) 137{ 138 print_keyring_serial_number(id); 139 tprintf(", %d, %d", user, group); 140} 141 142static void 143keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, long addr, 144 long len, key_serial_t id2) 145{ 146 print_keyring_serial_number(id1); 147 tprints(", "); 148 printstr(tcp, addr, len); 149 tprintf(", %lu, ", len); 150 print_keyring_serial_number(id2); 151} 152 153static void 154keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1, 155 long addr, long len, key_serial_t id2) 156{ 157 print_keyring_serial_number(id1); 158 tprints(", "); 159 tprint_iov(tcp, len, addr, 1); 160 tprintf(", %lu, ", len); 161 print_keyring_serial_number(id2); 162} 163 164static void 165keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout, 166 key_serial_t id2) 167{ 168 print_keyring_serial_number(id1); 169 tprintf(", %u, ", timeout); 170 print_keyring_serial_number(id2); 171} 172 173static void 174keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout, 175 unsigned error, key_serial_t id2) 176{ 177 print_keyring_serial_number(id1); 178 tprintf(", %u, %u, ", timeout, error); 179 print_keyring_serial_number(id2); 180} 181 182static void 183keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout) 184{ 185 print_keyring_serial_number(id); 186 tprintf(", %u", timeout); 187} 188 189static void 190keyctl_get_persistent(struct tcb *tcp, int uid, key_serial_t id) 191{ 192 tprintf("%d, ", uid); 193 print_keyring_serial_number(id); 194} 195 196#include "xlat/key_perms.h" 197 198static void 199keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm) 200{ 201 print_keyring_serial_number(id); 202 tprints(", "); 203 printflags(key_perms, perm, "KEY_???"); 204} 205 206#include "xlat/key_reqkeys.h" 207#include "xlat/keyctl_commands.h" 208 209SYS_FUNC(keyctl) 210{ 211 int cmd = tcp->u_arg[0]; 212 213 if (entering(tcp)) { 214 printxval(keyctl_commands, cmd, "KEYCTL_???"); 215 tprints(", "); 216 } 217 218 switch (cmd) { 219 case KEYCTL_GET_KEYRING_ID: 220 keyctl_get_keyring_id(tcp, tcp->u_arg[1], tcp->u_arg[2]); 221 break; 222 223 case KEYCTL_JOIN_SESSION_KEYRING: 224 printstr(tcp, tcp->u_arg[1], -1); 225 break; 226 227 case KEYCTL_UPDATE: 228 keyctl_update_key(tcp, tcp->u_arg[1], 229 tcp->u_arg[2], tcp->u_arg[3]); 230 break; 231 232 case KEYCTL_REVOKE: 233 case KEYCTL_CLEAR: 234 case KEYCTL_INVALIDATE: 235 case KEYCTL_ASSUME_AUTHORITY: 236 print_keyring_serial_number(tcp->u_arg[1]); 237 break; 238 239 case KEYCTL_LINK: 240 case KEYCTL_UNLINK: 241 keyctl_handle_key_key(tcp, tcp->u_arg[1], tcp->u_arg[2]); 242 break; 243 244 case KEYCTL_DESCRIBE: 245 case KEYCTL_READ: 246 case KEYCTL_GET_SECURITY: 247 keyctl_read_key(tcp, tcp->u_arg[1], 248 tcp->u_arg[2], tcp->u_arg[3]); 249 return 0; 250 251 case KEYCTL_SEARCH: 252 keyctl_keyring_search(tcp, tcp->u_arg[1], tcp->u_arg[2], 253 tcp->u_arg[3], tcp->u_arg[4]); 254 break; 255 256 case KEYCTL_CHOWN: 257 keyctl_chown_key(tcp, tcp->u_arg[1], 258 tcp->u_arg[2], tcp->u_arg[3]); 259 break; 260 261 case KEYCTL_SETPERM: 262 keyctl_setperm_key(tcp, tcp->u_arg[1], tcp->u_arg[2]); 263 break; 264 265 case KEYCTL_INSTANTIATE: 266 keyctl_instantiate_key(tcp, tcp->u_arg[1], tcp->u_arg[2], 267 tcp->u_arg[3], tcp->u_arg[4]); 268 break; 269 270 case KEYCTL_NEGATE: 271 keyctl_negate_key(tcp, tcp->u_arg[1], 272 tcp->u_arg[2], tcp->u_arg[3]); 273 break; 274 275 case KEYCTL_SET_REQKEY_KEYRING: 276 printxval(key_reqkeys, tcp->u_arg[1], "KEY_REQKEY_DEFL_???"); 277 break; 278 279 case KEYCTL_SET_TIMEOUT: 280 keyctl_set_timeout(tcp, tcp->u_arg[1], tcp->u_arg[2]); 281 break; 282 283 case KEYCTL_SESSION_TO_PARENT: 284 break; 285 286 case KEYCTL_REJECT: 287 keyctl_reject_key(tcp, tcp->u_arg[1], tcp->u_arg[2], 288 tcp->u_arg[3], tcp->u_arg[4]); 289 break; 290 291 case KEYCTL_INSTANTIATE_IOV: 292 keyctl_instantiate_key_iov(tcp, tcp->u_arg[1], 293 tcp->u_arg[2], tcp->u_arg[3], 294 tcp->u_arg[4]); 295 break; 296 297 case KEYCTL_GET_PERSISTENT: 298 keyctl_get_persistent(tcp, tcp->u_arg[1], tcp->u_arg[2]); 299 break; 300 301 default: 302 tprintf("%#lx, %#lx, %#lx, %#lx", 303 tcp->u_arg[1], tcp->u_arg[2], 304 tcp->u_arg[3], tcp->u_arg[4]); 305 break; 306 } 307 308 return RVAL_DECODED; 309} 310