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 typedef int32_t key_serial_t; 32 33 #include "xlat/key_spec.h" 34 35 struct keyctl_dh_params { 36 int32_t private; 37 int32_t prime; 38 int32_t base; 39 }; 40 41 static void 42 print_keyring_serial_number(key_serial_t id) 43 { 44 const char *str = xlookup(key_spec, (unsigned int) id); 45 46 if (str) 47 tprints(str); 48 else 49 tprintf("%d", id); 50 } 51 52 SYS_FUNC(add_key) 53 { 54 /* type */ 55 printstr(tcp, tcp->u_arg[0]); 56 /* description */ 57 tprints(", "); 58 printstr(tcp, tcp->u_arg[1]); 59 /* payload */ 60 tprints(", "); 61 printstrn(tcp, tcp->u_arg[2], tcp->u_arg[3]); 62 /* payload length */ 63 tprintf(", %" PRI_klu ", ", tcp->u_arg[3]); 64 /* keyring serial number */ 65 print_keyring_serial_number(tcp->u_arg[4]); 66 67 return RVAL_DECODED; 68 } 69 70 SYS_FUNC(request_key) 71 { 72 /* type */ 73 printstr(tcp, tcp->u_arg[0]); 74 /* description */ 75 tprints(", "); 76 printstr(tcp, tcp->u_arg[1]); 77 /* callout_info */ 78 tprints(", "); 79 printstr(tcp, tcp->u_arg[2]); 80 /* keyring serial number */ 81 tprints(", "); 82 print_keyring_serial_number(tcp->u_arg[3]); 83 84 return RVAL_DECODED; 85 } 86 87 static void 88 keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create) 89 { 90 print_keyring_serial_number(id); 91 tprintf(", %d", create); 92 } 93 94 static void 95 keyctl_update_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr, 96 kernel_ulong_t len) 97 { 98 print_keyring_serial_number(id); 99 tprints(", "); 100 printstrn(tcp, addr, len); 101 tprintf(", %llu", zero_extend_signed_to_ull(len)); 102 } 103 104 static void 105 keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2) 106 { 107 print_keyring_serial_number(id1); 108 tprints(", "); 109 print_keyring_serial_number(id2); 110 } 111 112 static void 113 keyctl_read_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr, 114 kernel_ulong_t len, bool has_nul) 115 { 116 if (entering(tcp)) { 117 print_keyring_serial_number(id); 118 tprints(", "); 119 } else { 120 if (syserror(tcp)) 121 printaddr(addr); 122 else { 123 kernel_ulong_t rval = (tcp->u_rval >= 0) && 124 ((kernel_ulong_t) tcp->u_rval > len) ? len : 125 (kernel_ulong_t) tcp->u_rval; 126 printstr_ex(tcp, addr, rval, has_nul ? 127 QUOTE_OMIT_TRAILING_0 : 0); 128 } 129 tprintf(", %llu", zero_extend_signed_to_ull(len)); 130 } 131 } 132 133 static void 134 keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr1, 135 kernel_ulong_t addr2, key_serial_t id2) 136 { 137 print_keyring_serial_number(id1); 138 tprints(", "); 139 printstr(tcp, addr1); 140 tprints(", "); 141 printstr(tcp, addr2); 142 tprints(", "); 143 print_keyring_serial_number(id2); 144 } 145 146 static void 147 keyctl_chown_key(struct tcb *tcp, key_serial_t id, unsigned user, 148 unsigned group) 149 { 150 print_keyring_serial_number(id); 151 printuid(", ", user); 152 printuid(", ", group); 153 } 154 155 static void 156 keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr, 157 kernel_ulong_t len, key_serial_t id2) 158 { 159 print_keyring_serial_number(id1); 160 tprints(", "); 161 printstrn(tcp, addr, len); 162 tprintf(", %llu, ", zero_extend_signed_to_ull(len)); 163 print_keyring_serial_number(id2); 164 } 165 166 static void 167 keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1, 168 kernel_ulong_t addr, kernel_ulong_t len, 169 key_serial_t id2) 170 { 171 print_keyring_serial_number(id1); 172 tprints(", "); 173 tprint_iov(tcp, len, addr, IOV_DECODE_STR); 174 tprintf(", %llu, ", zero_extend_signed_to_ull(len)); 175 print_keyring_serial_number(id2); 176 } 177 178 static void 179 keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout, 180 key_serial_t id2) 181 { 182 print_keyring_serial_number(id1); 183 tprintf(", %u, ", timeout); 184 print_keyring_serial_number(id2); 185 } 186 187 static void 188 keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout, 189 unsigned error, key_serial_t id2) 190 { 191 const char *err_str = err_name(error); 192 193 print_keyring_serial_number(id1); 194 tprintf(", %u, ", timeout); 195 196 if (err_str) 197 tprintf("%s, ", err_str); 198 else 199 tprintf("%u, ", error); 200 201 print_keyring_serial_number(id2); 202 } 203 204 static void 205 keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout) 206 { 207 print_keyring_serial_number(id); 208 tprintf(", %u", timeout); 209 } 210 211 static void 212 keyctl_get_persistent(struct tcb *tcp, unsigned uid, key_serial_t id) 213 { 214 printuid("", uid); 215 tprints(", "); 216 print_keyring_serial_number(id); 217 } 218 219 #include "xlat/key_perms.h" 220 221 static void 222 keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm) 223 { 224 print_keyring_serial_number(id); 225 tprints(", "); 226 printflags(key_perms, perm, "KEY_???"); 227 } 228 229 static void 230 print_dh_params(struct tcb *tcp, kernel_ulong_t addr) 231 { 232 struct keyctl_dh_params params; 233 234 if (umove_or_printaddr(tcp, addr, ¶ms)) 235 return; 236 237 tprints("{private="); 238 print_keyring_serial_number(params.private); 239 tprints(", prime="); 240 print_keyring_serial_number(params.prime); 241 tprints(", base="); 242 print_keyring_serial_number(params.base); 243 tprints("}"); 244 } 245 246 static void 247 keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf, 248 kernel_ulong_t len) 249 { 250 if (entering(tcp)) { 251 print_dh_params(tcp, params); 252 tprints(", "); 253 } else { 254 if (syserror(tcp)) { 255 printaddr(buf); 256 } else { 257 kernel_ulong_t rval = (tcp->u_rval >= 0) && 258 ((kernel_ulong_t) tcp->u_rval > len) ? len : 259 (kernel_ulong_t) tcp->u_rval; 260 printstrn(tcp, buf, rval); 261 } 262 tprintf(", %llu", zero_extend_signed_to_ull(len)); 263 } 264 } 265 266 #include "xlat/key_reqkeys.h" 267 #include "xlat/keyctl_commands.h" 268 269 SYS_FUNC(keyctl) 270 { 271 int cmd = tcp->u_arg[0]; 272 kernel_ulong_t arg2 = tcp->u_arg[1]; 273 kernel_ulong_t arg3 = tcp->u_arg[2]; 274 kernel_ulong_t arg4 = tcp->u_arg[3]; 275 kernel_ulong_t arg5 = tcp->u_arg[4]; 276 277 if (entering(tcp)) { 278 printxval(keyctl_commands, cmd, "KEYCTL_???"); 279 280 /* 281 * For now, KEYCTL_SESSION_TO_PARENT is the only cmd without 282 * arguments. 283 */ 284 if (cmd != KEYCTL_SESSION_TO_PARENT) 285 tprints(", "); 286 } 287 288 switch (cmd) { 289 case KEYCTL_GET_KEYRING_ID: 290 keyctl_get_keyring_id(tcp, arg2, arg3); 291 break; 292 293 case KEYCTL_JOIN_SESSION_KEYRING: 294 printstr(tcp, arg2); 295 break; 296 297 case KEYCTL_UPDATE: 298 keyctl_update_key(tcp, arg2, arg3, arg4); 299 break; 300 301 case KEYCTL_REVOKE: 302 case KEYCTL_CLEAR: 303 case KEYCTL_INVALIDATE: 304 case KEYCTL_ASSUME_AUTHORITY: 305 print_keyring_serial_number(arg2); 306 break; 307 308 case KEYCTL_LINK: 309 case KEYCTL_UNLINK: 310 keyctl_handle_key_key(tcp, arg2, arg3); 311 break; 312 313 case KEYCTL_DESCRIBE: 314 case KEYCTL_READ: 315 case KEYCTL_GET_SECURITY: 316 keyctl_read_key(tcp, arg2, arg3, arg4, cmd != KEYCTL_READ); 317 return 0; 318 319 case KEYCTL_SEARCH: 320 keyctl_keyring_search(tcp, arg2, arg3, arg4, arg5); 321 break; 322 323 case KEYCTL_CHOWN: 324 keyctl_chown_key(tcp, arg2, arg3, arg4); 325 break; 326 327 case KEYCTL_SETPERM: 328 keyctl_setperm_key(tcp, arg2, arg3); 329 break; 330 331 case KEYCTL_INSTANTIATE: 332 keyctl_instantiate_key(tcp, arg2, arg3, arg4, arg5); 333 break; 334 335 case KEYCTL_NEGATE: 336 keyctl_negate_key(tcp, arg2, arg3, arg4); 337 break; 338 339 case KEYCTL_SET_REQKEY_KEYRING: 340 printxval(key_reqkeys, arg2, "KEY_REQKEY_DEFL_???"); 341 break; 342 343 case KEYCTL_SET_TIMEOUT: 344 keyctl_set_timeout(tcp, arg2, arg3); 345 break; 346 347 case KEYCTL_SESSION_TO_PARENT: 348 break; 349 350 case KEYCTL_REJECT: 351 keyctl_reject_key(tcp, arg2, arg3, arg4, arg5); 352 break; 353 354 case KEYCTL_INSTANTIATE_IOV: 355 keyctl_instantiate_key_iov(tcp, arg2, arg3, arg4, arg5); 356 break; 357 358 case KEYCTL_GET_PERSISTENT: 359 keyctl_get_persistent(tcp, arg2, arg3); 360 break; 361 362 case KEYCTL_DH_COMPUTE: 363 keyctl_dh_compute(tcp, arg2, arg3, arg4); 364 return 0; 365 366 default: 367 tprintf("%#" PRI_klx ", %#" PRI_klx 368 ", %#" PRI_klx ", %#" PRI_klx, 369 arg2, arg3, arg4, arg5); 370 break; 371 } 372 373 return RVAL_DECODED; 374 } 375