1 /*
2 * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@strace.io>
3 * Copyright (c) 2014-2021 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #include "defs.h"
10
11 #include "keyctl_kdf_params.h"
12
13 #include "xlat/key_perms.h"
14 #include "xlat/key_reqkeys.h"
15 #include "xlat/key_spec.h"
16 #include "xlat/keyctl_caps0.h"
17 #include "xlat/keyctl_caps1.h"
18 #include "xlat/keyctl_commands.h"
19 #include "xlat/keyctl_move_flags.h"
20 #include "xlat/keyctl_pkey_ops.h"
21
22 typedef int32_t key_serial_t;
23
24 static void
25 print_keyring_serial_number(key_serial_t id)
26 {
27 printxval_d(key_spec, id, NULL);
28 }
29
30 SYS_FUNC(add_key)
31 {
32 /* type */
33 printstr(tcp, tcp->u_arg[0]);
34 tprint_arg_next();
35
36 /* description */
37 printstr(tcp, tcp->u_arg[1]);
38 tprint_arg_next();
39
40 /* payload */
41 printstrn(tcp, tcp->u_arg[2], tcp->u_arg[3]);
42 tprint_arg_next();
43
44 /* payload length */
45 PRINT_VAL_U(tcp->u_arg[3]);
46 tprint_arg_next();
47
48 /* keyring serial number */
49 print_keyring_serial_number(tcp->u_arg[4]);
50
51 return RVAL_DECODED;
52 }
53
54 SYS_FUNC(request_key)
55 {
56 /* type */
57 printstr(tcp, tcp->u_arg[0]);
58 tprint_arg_next();
59
60 /* description */
61 printstr(tcp, tcp->u_arg[1]);
62 tprint_arg_next();
63
64 /* callout_info */
65 printstr(tcp, tcp->u_arg[2]);
66 tprint_arg_next();
67
68 /* keyring serial number */
69 print_keyring_serial_number(tcp->u_arg[3]);
70
71 return RVAL_DECODED;
72 }
73
74 static void
75 keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create)
76 {
77 print_keyring_serial_number(id);
78 tprint_arg_next();
79
80 PRINT_VAL_D(create);
81 }
82
83 static void
84 keyctl_update_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
85 kernel_ulong_t len)
86 {
87 print_keyring_serial_number(id);
88 tprint_arg_next();
89
90 printstrn(tcp, addr, len);
91 tprint_arg_next();
92
93 PRINT_VAL_U(len);
94 }
95
96 static void
97 keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2)
98 {
99 print_keyring_serial_number(id1);
100 tprint_arg_next();
101
102 print_keyring_serial_number(id2);
103 }
104
105 static void
106 keyctl_read_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
107 kernel_ulong_t len, bool has_nul)
108 {
109 if (entering(tcp)) {
110 print_keyring_serial_number(id);
111 tprint_arg_next();
112 } else {
113 if (syserror(tcp))
114 printaddr(addr);
115 else {
116 kernel_ulong_t rval = (tcp->u_rval >= 0) &&
117 ((kernel_ulong_t) tcp->u_rval > len) ? len :
118 (kernel_ulong_t) tcp->u_rval;
119 printstr_ex(tcp, addr, rval, has_nul ?
120 QUOTE_OMIT_TRAILING_0 : 0);
121 }
122 tprint_arg_next();
123
124 PRINT_VAL_U(len);
125 }
126 }
127
128 static void
129 keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr1,
130 kernel_ulong_t addr2, key_serial_t id2)
131 {
132 print_keyring_serial_number(id1);
133 tprint_arg_next();
134
135 printstr(tcp, addr1);
136 tprint_arg_next();
137
138 printstr(tcp, addr2);
139 tprint_arg_next();
140
141 print_keyring_serial_number(id2);
142 }
143
144 static void
145 keyctl_chown_key(struct tcb *tcp, key_serial_t id, unsigned user,
146 unsigned group)
147 {
148 print_keyring_serial_number(id);
149 tprint_arg_next();
150
151 printuid(user);
152 tprint_arg_next();
153
154 printuid(group);
155 }
156
157 static void
158 keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr,
159 kernel_ulong_t len, key_serial_t id2)
160 {
161 print_keyring_serial_number(id1);
162 tprint_arg_next();
163
164 printstrn(tcp, addr, len);
165 tprint_arg_next();
166
167 PRINT_VAL_U(len);
168 tprint_arg_next();
169
170 print_keyring_serial_number(id2);
171 }
172
173 static void
174 keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
175 kernel_ulong_t addr, kernel_ulong_t len,
176 key_serial_t id2)
177 {
178 print_keyring_serial_number(id1);
179 tprint_arg_next();
180
181 tprint_iov(tcp, len, addr, iov_decode_str);
182 tprint_arg_next();
183
184 PRINT_VAL_U(len);
185 tprint_arg_next();
186
187 print_keyring_serial_number(id2);
188 }
189
190 static void
191 keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
192 key_serial_t id2)
193 {
194 print_keyring_serial_number(id1);
195 tprint_arg_next();
196
197 PRINT_VAL_U(timeout);
198 tprint_arg_next();
199
200 print_keyring_serial_number(id2);
201 }
202
203 static void
204 keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
205 unsigned error, key_serial_t id2)
206 {
207 print_keyring_serial_number(id1);
208 tprint_arg_next();
209
210 PRINT_VAL_U(timeout);
211 tprint_arg_next();
212
213 print_err(error, false);
214 tprint_arg_next();
215
216 print_keyring_serial_number(id2);
217 }
218
219 static void
220 keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout)
221 {
222 print_keyring_serial_number(id);
223 tprint_arg_next();
224
225 PRINT_VAL_U(timeout);
226 }
227
228 static void
229 keyctl_get_persistent(struct tcb *tcp, unsigned uid, key_serial_t id)
230 {
231 printuid(uid);
232 tprint_arg_next();
233
234 print_keyring_serial_number(id);
235 }
236
237 static void
238 keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm)
239 {
240 print_keyring_serial_number(id);
241 tprint_arg_next();
242
243 printflags(key_perms, perm, "KEY_???");
244 }
245
246 static void
247 print_dh_params(struct tcb *tcp, kernel_ulong_t addr)
248 {
249 struct keyctl_dh_params params;
250
251 if (umove_or_printaddr(tcp, addr, ¶ms))
252 return;
253
254 tprint_struct_begin();
255 PRINT_FIELD_OBJ_VAL(params, private, print_keyring_serial_number);
256 tprint_struct_next();
257 PRINT_FIELD_OBJ_VAL(params, prime, print_keyring_serial_number);
258 tprint_struct_next();
259 PRINT_FIELD_OBJ_VAL(params, base, print_keyring_serial_number);
260 tprint_struct_end();
261 }
262
263 static void
264 keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf,
265 kernel_ulong_t len, kernel_ulong_t kdf_addr)
266 {
267 if (entering(tcp)) {
268 print_dh_params(tcp, params);
269 tprint_arg_next();
270 } else {
271 struct strace_keyctl_kdf_params kdf;
272
273 if (syserror(tcp)) {
274 printaddr(buf);
275 } else {
276 kernel_ulong_t rval = (tcp->u_rval >= 0) &&
277 ((kernel_ulong_t) tcp->u_rval > len) ? len :
278 (kernel_ulong_t) tcp->u_rval;
279 printstrn(tcp, buf, rval);
280 }
281 tprint_arg_next();
282
283 PRINT_VAL_U(len);
284 tprint_arg_next();
285
286 if (fetch_keyctl_kdf_params(tcp, kdf_addr, &kdf)) {
287 printaddr(kdf_addr);
288 } else {
289 tprint_struct_begin();
290 PRINT_FIELD_OBJ_TCB_VAL(kdf, hashname, tcp,
291 printstr);
292
293 /*
294 * Kernel doesn't touch otherinfo
295 * if otherinfolen is zero.
296 */
297 if (kdf.otherinfolen) {
298 tprint_struct_next();
299 PRINT_FIELD_OBJ_TCB_VAL(kdf, otherinfo,
300 tcp, printstrn, kdf.otherinfolen);
301 } else {
302 tprint_struct_next();
303 PRINT_FIELD_PTR(kdf, otherinfo);
304 }
305
306 tprint_struct_next();
307 PRINT_FIELD_U(kdf, otherinfolen);
308
309 if (!IS_ARRAY_ZERO(kdf.__spare)) {
310 tprint_struct_next();
311 PRINT_FIELD_ARRAY(kdf, __spare, tcp,
312 print_xint_array_member);
313 }
314
315 tprint_struct_end();
316 }
317 }
318 }
319
320 static void
321 print_pkey_query(struct tcb *tcp, kernel_ulong_t addr)
322 {
323 struct keyctl_pkey_query query;
324
325 if (umove_or_printaddr(tcp, addr, &query))
326 return;
327
328 tprint_struct_begin();
329 PRINT_FIELD_FLAGS(query, supported_ops, keyctl_pkey_ops,
330 "KEYCTL_SUPPORTS_???");
331 tprint_struct_next();
332 PRINT_FIELD_U(query, key_size);
333 tprint_struct_next();
334 PRINT_FIELD_U(query, max_data_size);
335 tprint_struct_next();
336 PRINT_FIELD_U(query, max_sig_size);
337 tprint_struct_next();
338 PRINT_FIELD_U(query, max_enc_size);
339 tprint_struct_next();
340 PRINT_FIELD_U(query, max_dec_size);
341
342 if (!IS_ARRAY_ZERO(query.__spare)) {
343 tprint_struct_next();
344 PRINT_FIELD_ARRAY(query, __spare, tcp,
345 print_xint_array_member);
346 }
347
348 tprint_struct_end();
349 }
350
351 static void
352 keyctl_pkey_query(struct tcb *const tcp,
353 const key_serial_t id,
354 const kernel_ulong_t reserved,
355 const kernel_ulong_t /* char * */ info,
356 const kernel_ulong_t /* keyctl_pkey_query * */ res)
357 {
358 if (entering(tcp)) {
359 print_keyring_serial_number(id);
360 tprint_arg_next();
361
362 PRINT_VAL_X(reserved);
363 tprint_arg_next();
364
365 printstr(tcp, info);
366 tprint_arg_next();
367 } else {
368 print_pkey_query(tcp, res);
369 }
370 }
371
372 static bool
373 fetch_print_pkey_params(struct tcb *tcp, kernel_ulong_t addr,
374 struct keyctl_pkey_params *params, bool out)
375 {
376 if (umove_or_printaddr(tcp, addr, params))
377 return false;
378
379 tprint_struct_begin();
380 PRINT_FIELD_OBJ_VAL(*params, key_id, print_keyring_serial_number);
381 tprint_struct_next();
382 PRINT_FIELD_U(*params, in_len);
383
384 if (out) {
385 tprint_struct_next();
386 PRINT_FIELD_U(*params, out_len);
387 } else {
388 tprint_struct_next();
389 PRINT_FIELD_U(*params, in2_len);
390 }
391
392 if (!IS_ARRAY_ZERO(params->__spare)) {
393 tprint_struct_next();
394 PRINT_FIELD_ARRAY(*params, __spare, tcp,
395 print_xint_array_member);
396 }
397
398 tprint_struct_end();
399
400 return true;
401 }
402
403 static int
404 keyctl_pkey_op(struct tcb *const tcp,
405 const kernel_ulong_t /* keyctl_pkey_params * */ params_addr,
406 const kernel_ulong_t /* char * */ info,
407 const kernel_ulong_t /* void * */ op1,
408 const kernel_ulong_t /* void * */ op2,
409 bool out)
410 {
411 if (entering(tcp)) {
412 struct keyctl_pkey_params params;
413 bool ret;
414
415 ret = fetch_print_pkey_params(tcp, params_addr, ¶ms, out);
416 if (ret && out)
417 set_tcb_priv_ulong(tcp, params.out_len);
418
419 tprint_arg_next();
420 printstr(tcp, info);
421 tprint_arg_next();
422
423 if (ret)
424 printstrn(tcp, op1, params.in_len);
425 else
426 printaddr(op1);
427 tprint_arg_next();
428
429 if (!out || !ret) {
430 if (ret)
431 printstrn(tcp, op2, params.in2_len);
432 else
433 printaddr(op2);
434 }
435
436 return ret && out ? 0 : RVAL_DECODED;
437 } else {
438 unsigned long out_len = get_tcb_priv_ulong(tcp);
439
440 if (syserror(tcp))
441 printaddr(op2);
442 else
443 printstrn(tcp, op2, out_len);
444 }
445
446 return 0;
447 }
448
449 static void
450 keyctl_restrict_keyring(struct tcb *const tcp,
451 const key_serial_t id,
452 const kernel_ulong_t addr1,
453 const kernel_ulong_t addr2)
454 {
455 print_keyring_serial_number(id);
456 tprint_arg_next();
457
458 printstr(tcp, addr1);
459 tprint_arg_next();
460
461 printstr(tcp, addr2);
462 }
463
464 static void
465 keyctl_move(struct tcb *const tcp,
466 const key_serial_t id,
467 const key_serial_t from,
468 const key_serial_t to,
469 const unsigned int flags)
470 {
471 print_keyring_serial_number(id);
472 tprint_arg_next();
473
474 print_keyring_serial_number(from);
475 tprint_arg_next();
476
477 print_keyring_serial_number(to);
478 tprint_arg_next();
479
480 printflags(keyctl_move_flags, flags, "KEYCTL_MOVE_???");
481 }
482
483 static bool
484 print_keyctl_caps(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
485 {
486 static const struct {
487 const struct xlat *xlat;
488 const char *dflt;
489 } caps[] = {
490 { keyctl_caps0, "KEYCTL_CAPS0_???" },
491 { keyctl_caps1, "KEYCTL_CAPS1_???" },
492 };
493
494 kernel_ulong_t *pos = data;
495 unsigned char *elem = elem_buf;
496
497 if (*pos < ARRAY_SIZE(caps))
498 printflags(caps[*pos].xlat, *elem, caps[*pos].dflt);
499 else
500 PRINT_VAL_X(*elem);
501
502 (*pos)++;
503
504 return true;
505 }
506
507 static void
508 keyctl_capabilities(struct tcb *const tcp,
509 const kernel_ulong_t /* char * */ buf,
510 const kernel_ulong_t buflen)
511 {
512 kernel_ulong_t pos = 0;
513 unsigned char elem;
514
515 if (entering(tcp))
516 return;
517
518 if (syserror(tcp)) {
519 printaddr(buf);
520 } else {
521 print_array(tcp, buf, MIN(buflen, (kernel_ulong_t) tcp->u_rval),
522 &elem, sizeof(elem),
523 tfetch_mem, print_keyctl_caps, &pos);
524 }
525 tprint_arg_next();
526
527 PRINT_VAL_U(buflen);
528 }
529
530 SYS_FUNC(keyctl)
531 {
532 int cmd = tcp->u_arg[0];
533 kernel_ulong_t arg2 = tcp->u_arg[1];
534 kernel_ulong_t arg3 = tcp->u_arg[2];
535 kernel_ulong_t arg4 = tcp->u_arg[3];
536 kernel_ulong_t arg5 = tcp->u_arg[4];
537
538 if (entering(tcp)) {
539 printxval(keyctl_commands, cmd, "KEYCTL_???");
540
541 /*
542 * For now, KEYCTL_SESSION_TO_PARENT is the only cmd without
543 * arguments.
544 */
545 if (cmd != KEYCTL_SESSION_TO_PARENT)
546 tprint_arg_next();
547 }
548
549 switch (cmd) {
550 case KEYCTL_GET_KEYRING_ID:
551 keyctl_get_keyring_id(tcp, arg2, arg3);
552 break;
553
554 case KEYCTL_JOIN_SESSION_KEYRING:
555 printstr(tcp, arg2);
556 break;
557
558 case KEYCTL_UPDATE:
559 keyctl_update_key(tcp, arg2, arg3, arg4);
560 break;
561
562 case KEYCTL_REVOKE:
563 case KEYCTL_CLEAR:
564 case KEYCTL_INVALIDATE:
565 case KEYCTL_ASSUME_AUTHORITY:
566 print_keyring_serial_number(arg2);
567 break;
568
569 case KEYCTL_LINK:
570 case KEYCTL_UNLINK:
571 keyctl_handle_key_key(tcp, arg2, arg3);
572 break;
573
574 case KEYCTL_DESCRIBE:
575 case KEYCTL_READ:
576 case KEYCTL_GET_SECURITY:
577 keyctl_read_key(tcp, arg2, arg3, arg4, cmd != KEYCTL_READ);
578 return 0;
579
580 case KEYCTL_SEARCH:
581 keyctl_keyring_search(tcp, arg2, arg3, arg4, arg5);
582 break;
583
584 case KEYCTL_CHOWN:
585 keyctl_chown_key(tcp, arg2, arg3, arg4);
586 break;
587
588 case KEYCTL_SETPERM:
589 keyctl_setperm_key(tcp, arg2, arg3);
590 break;
591
592 case KEYCTL_INSTANTIATE:
593 keyctl_instantiate_key(tcp, arg2, arg3, arg4, arg5);
594 break;
595
596 case KEYCTL_NEGATE:
597 keyctl_negate_key(tcp, arg2, arg3, arg4);
598 break;
599
600 case KEYCTL_SET_REQKEY_KEYRING:
601 printxvals_ex((int) arg2, "KEY_REQKEY_DEFL_???",
602 XLAT_STYLE_FMT_D, key_reqkeys, NULL);
603 break;
604
605 case KEYCTL_SET_TIMEOUT:
606 keyctl_set_timeout(tcp, arg2, arg3);
607 break;
608
609 case KEYCTL_SESSION_TO_PARENT:
610 break;
611
612 case KEYCTL_REJECT:
613 keyctl_reject_key(tcp, arg2, arg3, arg4, arg5);
614 break;
615
616 case KEYCTL_INSTANTIATE_IOV:
617 keyctl_instantiate_key_iov(tcp, arg2, arg3, arg4, arg5);
618 break;
619
620 case KEYCTL_GET_PERSISTENT:
621 keyctl_get_persistent(tcp, arg2, arg3);
622 break;
623
624 case KEYCTL_DH_COMPUTE:
625 keyctl_dh_compute(tcp, arg2, arg3, arg4, arg5);
626 return 0;
627
628 case KEYCTL_PKEY_QUERY:
629 keyctl_pkey_query(tcp, arg2, arg3, arg4, arg5);
630 return 0;
631
632 case KEYCTL_PKEY_ENCRYPT:
633 case KEYCTL_PKEY_DECRYPT:
634 case KEYCTL_PKEY_SIGN:
635 return keyctl_pkey_op(tcp, arg2, arg3, arg4, arg5, true);
636
637 case KEYCTL_PKEY_VERIFY:
638 keyctl_pkey_op(tcp, arg2, arg3, arg4, arg5, false);
639 break;
640
641 case KEYCTL_RESTRICT_KEYRING:
642 keyctl_restrict_keyring(tcp, arg2, arg3, arg4);
643 break;
644
645 case KEYCTL_MOVE:
646 keyctl_move(tcp, arg2, arg3, arg4, arg5);
647 break;
648
649 case KEYCTL_CAPABILITIES:
650 keyctl_capabilities(tcp, arg2, arg3);
651 return 0;
652
653 default:
654 PRINT_VAL_X(arg2);
655 tprint_arg_next();
656
657 PRINT_VAL_X(arg3);
658 tprint_arg_next();
659
660 PRINT_VAL_X(arg4);
661 tprint_arg_next();
662
663 PRINT_VAL_X(arg5);
664 break;
665 }
666
667 return RVAL_DECODED;
668 }