1 /* 2 * Copyright (c) 2014-2015 Dmitry V. Levin <ldv (at) altlinux.org> 3 * Copyright (c) 2014-2017 The strace developers. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "defs.h" 30 31 #include "keyctl_kdf_params.h" 32 #include "print_fields.h" 33 34 typedef int32_t key_serial_t; 35 36 #include "xlat/key_spec.h" 37 38 struct keyctl_dh_params { 39 int32_t private; 40 int32_t prime; 41 int32_t base; 42 }; 43 44 static void 45 print_keyring_serial_number(key_serial_t id) 46 { 47 const char *str = xlookup(key_spec, (unsigned int) id); 48 49 if (str) 50 tprints(str); 51 else 52 tprintf("%d", id); 53 } 54 55 SYS_FUNC(add_key) 56 { 57 /* type */ 58 printstr(tcp, tcp->u_arg[0]); 59 /* description */ 60 tprints(", "); 61 printstr(tcp, tcp->u_arg[1]); 62 /* payload */ 63 tprints(", "); 64 printstrn(tcp, tcp->u_arg[2], tcp->u_arg[3]); 65 /* payload length */ 66 tprintf(", %" PRI_klu ", ", tcp->u_arg[3]); 67 /* keyring serial number */ 68 print_keyring_serial_number(tcp->u_arg[4]); 69 70 return RVAL_DECODED; 71 } 72 73 SYS_FUNC(request_key) 74 { 75 /* type */ 76 printstr(tcp, tcp->u_arg[0]); 77 /* description */ 78 tprints(", "); 79 printstr(tcp, tcp->u_arg[1]); 80 /* callout_info */ 81 tprints(", "); 82 printstr(tcp, tcp->u_arg[2]); 83 /* keyring serial number */ 84 tprints(", "); 85 print_keyring_serial_number(tcp->u_arg[3]); 86 87 return RVAL_DECODED; 88 } 89 90 static void 91 keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create) 92 { 93 print_keyring_serial_number(id); 94 tprintf(", %d", create); 95 } 96 97 static void 98 keyctl_update_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr, 99 kernel_ulong_t len) 100 { 101 print_keyring_serial_number(id); 102 tprints(", "); 103 printstrn(tcp, addr, len); 104 tprintf(", %llu", zero_extend_signed_to_ull(len)); 105 } 106 107 static void 108 keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2) 109 { 110 print_keyring_serial_number(id1); 111 tprints(", "); 112 print_keyring_serial_number(id2); 113 } 114 115 static void 116 keyctl_read_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr, 117 kernel_ulong_t len, bool has_nul) 118 { 119 if (entering(tcp)) { 120 print_keyring_serial_number(id); 121 tprints(", "); 122 } else { 123 if (syserror(tcp)) 124 printaddr(addr); 125 else { 126 kernel_ulong_t rval = (tcp->u_rval >= 0) && 127 ((kernel_ulong_t) tcp->u_rval > len) ? len : 128 (kernel_ulong_t) tcp->u_rval; 129 printstr_ex(tcp, addr, rval, has_nul ? 130 QUOTE_OMIT_TRAILING_0 : 0); 131 } 132 tprintf(", %llu", zero_extend_signed_to_ull(len)); 133 } 134 } 135 136 static void 137 keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr1, 138 kernel_ulong_t addr2, key_serial_t id2) 139 { 140 print_keyring_serial_number(id1); 141 tprints(", "); 142 printstr(tcp, addr1); 143 tprints(", "); 144 printstr(tcp, addr2); 145 tprints(", "); 146 print_keyring_serial_number(id2); 147 } 148 149 static void 150 keyctl_chown_key(struct tcb *tcp, key_serial_t id, unsigned user, 151 unsigned group) 152 { 153 print_keyring_serial_number(id); 154 printuid(", ", user); 155 printuid(", ", group); 156 } 157 158 static void 159 keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr, 160 kernel_ulong_t len, key_serial_t id2) 161 { 162 print_keyring_serial_number(id1); 163 tprints(", "); 164 printstrn(tcp, addr, len); 165 tprintf(", %llu, ", zero_extend_signed_to_ull(len)); 166 print_keyring_serial_number(id2); 167 } 168 169 static void 170 keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1, 171 kernel_ulong_t addr, kernel_ulong_t len, 172 key_serial_t id2) 173 { 174 print_keyring_serial_number(id1); 175 tprints(", "); 176 tprint_iov(tcp, len, addr, IOV_DECODE_STR); 177 tprintf(", %llu, ", zero_extend_signed_to_ull(len)); 178 print_keyring_serial_number(id2); 179 } 180 181 static void 182 keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout, 183 key_serial_t id2) 184 { 185 print_keyring_serial_number(id1); 186 tprintf(", %u, ", timeout); 187 print_keyring_serial_number(id2); 188 } 189 190 static void 191 keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout, 192 unsigned error, key_serial_t id2) 193 { 194 const char *err_str = err_name(error); 195 196 print_keyring_serial_number(id1); 197 tprintf(", %u, ", timeout); 198 199 if (err_str) 200 tprintf("%s, ", err_str); 201 else 202 tprintf("%u, ", error); 203 204 print_keyring_serial_number(id2); 205 } 206 207 static void 208 keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout) 209 { 210 print_keyring_serial_number(id); 211 tprintf(", %u", timeout); 212 } 213 214 static void 215 keyctl_get_persistent(struct tcb *tcp, unsigned uid, key_serial_t id) 216 { 217 printuid("", uid); 218 tprints(", "); 219 print_keyring_serial_number(id); 220 } 221 222 #include "xlat/key_perms.h" 223 224 static void 225 keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm) 226 { 227 print_keyring_serial_number(id); 228 tprints(", "); 229 printflags(key_perms, perm, "KEY_???"); 230 } 231 232 static void 233 print_dh_params(struct tcb *tcp, kernel_ulong_t addr) 234 { 235 struct keyctl_dh_params params; 236 237 if (umove_or_printaddr(tcp, addr, ¶ms)) 238 return; 239 240 tprints("{private="); 241 print_keyring_serial_number(params.private); 242 tprints(", prime="); 243 print_keyring_serial_number(params.prime); 244 tprints(", base="); 245 print_keyring_serial_number(params.base); 246 tprints("}"); 247 } 248 249 static void 250 keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf, 251 kernel_ulong_t len, kernel_ulong_t kdf_addr) 252 { 253 if (entering(tcp)) { 254 print_dh_params(tcp, params); 255 tprints(", "); 256 } else { 257 struct strace_keyctl_kdf_params kdf; 258 259 if (syserror(tcp)) { 260 printaddr(buf); 261 } else { 262 kernel_ulong_t rval = (tcp->u_rval >= 0) && 263 ((kernel_ulong_t) tcp->u_rval > len) ? len : 264 (kernel_ulong_t) tcp->u_rval; 265 printstrn(tcp, buf, rval); 266 } 267 tprintf(", %llu, ", zero_extend_signed_to_ull(len)); 268 269 if (fetch_keyctl_kdf_params(tcp, kdf_addr, &kdf)) { 270 printaddr(kdf_addr); 271 } else { 272 size_t i; 273 274 PRINT_FIELD_STR("{", kdf, hashname, tcp); 275 276 /* 277 * Kernel doesn't touch otherinfo 278 * if otherinfolen is zero. 279 */ 280 if (kdf.otherinfolen) 281 PRINT_FIELD_STRN(", ", kdf, otherinfo, 282 kdf.otherinfolen, tcp); 283 else 284 PRINT_FIELD_PTR(", ", kdf, otherinfo); 285 286 PRINT_FIELD_U(", ", kdf, otherinfolen); 287 288 /* Some future-proofing */ 289 for (i = 0; i < ARRAY_SIZE(kdf.__spare); i++) { 290 if (kdf.__spare[i]) 291 break; 292 } 293 294 if (i < ARRAY_SIZE(kdf.__spare)) { 295 tprints(", __spare=["); 296 297 for (i = 0; i < ARRAY_SIZE(kdf.__spare); i++) { 298 if (i) 299 tprints(", "); 300 301 tprintf("%#x", kdf.__spare[i]); 302 } 303 304 tprints("]"); 305 } 306 307 tprints("}"); 308 } 309 } 310 } 311 312 static void 313 keyctl_restrict_keyring(struct tcb *const tcp, 314 const key_serial_t id, 315 const kernel_ulong_t addr1, 316 const kernel_ulong_t addr2) 317 { 318 print_keyring_serial_number(id); 319 tprints(", "); 320 printstr(tcp, addr1); 321 tprints(", "); 322 printstr(tcp, addr2); 323 } 324 325 #include "xlat/key_reqkeys.h" 326 #include "xlat/keyctl_commands.h" 327 328 SYS_FUNC(keyctl) 329 { 330 int cmd = tcp->u_arg[0]; 331 kernel_ulong_t arg2 = tcp->u_arg[1]; 332 kernel_ulong_t arg3 = tcp->u_arg[2]; 333 kernel_ulong_t arg4 = tcp->u_arg[3]; 334 kernel_ulong_t arg5 = tcp->u_arg[4]; 335 336 if (entering(tcp)) { 337 printxval(keyctl_commands, cmd, "KEYCTL_???"); 338 339 /* 340 * For now, KEYCTL_SESSION_TO_PARENT is the only cmd without 341 * arguments. 342 */ 343 if (cmd != KEYCTL_SESSION_TO_PARENT) 344 tprints(", "); 345 } 346 347 switch (cmd) { 348 case KEYCTL_GET_KEYRING_ID: 349 keyctl_get_keyring_id(tcp, arg2, arg3); 350 break; 351 352 case KEYCTL_JOIN_SESSION_KEYRING: 353 printstr(tcp, arg2); 354 break; 355 356 case KEYCTL_UPDATE: 357 keyctl_update_key(tcp, arg2, arg3, arg4); 358 break; 359 360 case KEYCTL_REVOKE: 361 case KEYCTL_CLEAR: 362 case KEYCTL_INVALIDATE: 363 case KEYCTL_ASSUME_AUTHORITY: 364 print_keyring_serial_number(arg2); 365 break; 366 367 case KEYCTL_LINK: 368 case KEYCTL_UNLINK: 369 keyctl_handle_key_key(tcp, arg2, arg3); 370 break; 371 372 case KEYCTL_DESCRIBE: 373 case KEYCTL_READ: 374 case KEYCTL_GET_SECURITY: 375 keyctl_read_key(tcp, arg2, arg3, arg4, cmd != KEYCTL_READ); 376 return 0; 377 378 case KEYCTL_SEARCH: 379 keyctl_keyring_search(tcp, arg2, arg3, arg4, arg5); 380 break; 381 382 case KEYCTL_CHOWN: 383 keyctl_chown_key(tcp, arg2, arg3, arg4); 384 break; 385 386 case KEYCTL_SETPERM: 387 keyctl_setperm_key(tcp, arg2, arg3); 388 break; 389 390 case KEYCTL_INSTANTIATE: 391 keyctl_instantiate_key(tcp, arg2, arg3, arg4, arg5); 392 break; 393 394 case KEYCTL_NEGATE: 395 keyctl_negate_key(tcp, arg2, arg3, arg4); 396 break; 397 398 case KEYCTL_SET_REQKEY_KEYRING: 399 printxval(key_reqkeys, arg2, "KEY_REQKEY_DEFL_???"); 400 break; 401 402 case KEYCTL_SET_TIMEOUT: 403 keyctl_set_timeout(tcp, arg2, arg3); 404 break; 405 406 case KEYCTL_SESSION_TO_PARENT: 407 break; 408 409 case KEYCTL_REJECT: 410 keyctl_reject_key(tcp, arg2, arg3, arg4, arg5); 411 break; 412 413 case KEYCTL_INSTANTIATE_IOV: 414 keyctl_instantiate_key_iov(tcp, arg2, arg3, arg4, arg5); 415 break; 416 417 case KEYCTL_GET_PERSISTENT: 418 keyctl_get_persistent(tcp, arg2, arg3); 419 break; 420 421 case KEYCTL_DH_COMPUTE: 422 keyctl_dh_compute(tcp, arg2, arg3, arg4, arg5); 423 return 0; 424 425 case KEYCTL_RESTRICT_KEYRING: 426 keyctl_restrict_keyring(tcp, arg2, arg3, arg4); 427 break; 428 429 default: 430 tprintf("%#" PRI_klx ", %#" PRI_klx 431 ", %#" PRI_klx ", %#" PRI_klx, 432 arg2, arg3, arg4, arg5); 433 break; 434 } 435 436 return RVAL_DECODED; 437 } 438