]> granicus.if.org Git - strace/blob - keyctl.c
Remove linux/ptp_clock.h
[strace] / keyctl.c
1 /*
2  * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@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, &params))
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 }