]> granicus.if.org Git - strace/blob - keyctl.c
netlink_sock_diag: print inet_diag_sockid.idiag_if as an interface index
[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 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, &params))
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 }