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