Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
3 : : * All rights reserved.
4 : : *
5 : : * Redistribution and use in source and binary forms, with or without
6 : : * modification, are permitted provided that the following conditions
7 : : * are met:
8 : : * 1. Redistributions of source code must retain the above copyright
9 : : * notice, this list of conditions and the following disclaimer.
10 : : * 2. Redistributions in binary form must reproduce the above copyright
11 : : * notice, this list of conditions and the following disclaimer in the
12 : : * documentation and/or other materials provided with the distribution.
13 : : * 3. The name of the author may not be used to endorse or promote products
14 : : * derived from this software without specific prior written permission.
15 : : *
16 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : : */
27 : :
28 : : #include "defs.h"
29 : :
30 : : typedef int32_t key_serial_t;
31 : :
32 : : #include "xlat/key_spec.h"
33 : :
34 : : struct keyctl_dh_params {
35 : : int32_t private;
36 : : int32_t prime;
37 : : int32_t base;
38 : : };
39 : :
40 : : static void
41 : 9330 : print_keyring_serial_number(key_serial_t id)
42 : : {
43 : 9330 : const char *str = xlookup(key_spec, (unsigned int) id);
44 : :
45 [ + + ]: 9330 : if (str)
46 : 2358 : tprints(str);
47 : : else
48 : 6972 : tprintf("%d", id);
49 : 9330 : }
50 : :
51 : 4320 : SYS_FUNC(add_key)
52 : : {
53 : : /* type */
54 : 4320 : printstr(tcp, tcp->u_arg[0]);
55 : : /* description */
56 : 4320 : tprints(", ");
57 : 4320 : printstr(tcp, tcp->u_arg[1]);
58 : : /* payload */
59 : 4320 : tprints(", ");
60 : 4320 : printstrn(tcp, tcp->u_arg[2], tcp->u_arg[3]);
61 : : /* payload length */
62 : 4320 : tprintf(", %" PRI_klu ", ", tcp->u_arg[3]);
63 : : /* keyring serial number */
64 : 4320 : print_keyring_serial_number(tcp->u_arg[4]);
65 : :
66 : 4320 : return RVAL_DECODED;
67 : : }
68 : :
69 : 4320 : SYS_FUNC(request_key)
70 : : {
71 : : /* type */
72 : 4320 : printstr(tcp, tcp->u_arg[0]);
73 : : /* description */
74 : 4320 : tprints(", ");
75 : 4320 : printstr(tcp, tcp->u_arg[1]);
76 : : /* callout_info */
77 : 4320 : tprints(", ");
78 : 4320 : printstr(tcp, tcp->u_arg[2]);
79 : : /* keyring serial number */
80 : 4320 : tprints(", ");
81 : 4320 : print_keyring_serial_number(tcp->u_arg[3]);
82 : :
83 : 4320 : return RVAL_DECODED;
84 : : }
85 : :
86 : : static void
87 : 12 : keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create)
88 : : {
89 : 12 : print_keyring_serial_number(id);
90 : 12 : tprintf(", %d", create);
91 : 12 : }
92 : :
93 : : static void
94 : 24 : keyctl_update_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
95 : : kernel_ulong_t len)
96 : : {
97 : 24 : print_keyring_serial_number(id);
98 : 24 : tprints(", ");
99 : 24 : printstrn(tcp, addr, len);
100 : 24 : tprintf(", %llu", zero_extend_signed_to_ull(len));
101 : 24 : }
102 : :
103 : : static void
104 : 36 : keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2)
105 : : {
106 : 36 : print_keyring_serial_number(id1);
107 : 36 : tprints(", ");
108 : 36 : print_keyring_serial_number(id2);
109 : 36 : }
110 : :
111 : : static void
112 : 180 : keyctl_read_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
113 : : kernel_ulong_t len, bool has_nul)
114 : : {
115 [ + + ]: 180 : if (entering(tcp)) {
116 : 90 : print_keyring_serial_number(id);
117 : 90 : tprints(", ");
118 : : } else {
119 [ + + ]: 90 : if (syserror(tcp))
120 : 42 : printaddr(addr);
121 : : else {
122 [ + + ]: 48 : kernel_ulong_t rval = (tcp->u_rval >= 0) &&
123 [ + - ]: 96 : ((kernel_ulong_t) tcp->u_rval > len) ? len :
124 : 36 : (kernel_ulong_t) tcp->u_rval;
125 [ + + ]: 48 : printstr_ex(tcp, addr, rval, has_nul ?
126 : : QUOTE_OMIT_TRAILING_0 : 0);
127 : : }
128 : 90 : tprintf(", %llu", zero_extend_signed_to_ull(len));
129 : : }
130 : 180 : }
131 : :
132 : : static void
133 : 30 : keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr1,
134 : : kernel_ulong_t addr2, key_serial_t id2)
135 : : {
136 : 30 : print_keyring_serial_number(id1);
137 : 30 : tprints(", ");
138 : 30 : printstr(tcp, addr1);
139 : 30 : tprints(", ");
140 : 30 : printstr(tcp, addr2);
141 : 30 : tprints(", ");
142 : 30 : print_keyring_serial_number(id2);
143 : 30 : }
144 : :
145 : : static void
146 : 12 : keyctl_chown_key(struct tcb *tcp, key_serial_t id, unsigned user,
147 : : unsigned group)
148 : : {
149 : 12 : print_keyring_serial_number(id);
150 : 12 : printuid(", ", user);
151 : 12 : printuid(", ", group);
152 : 12 : }
153 : :
154 : : static void
155 : 30 : keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr,
156 : : kernel_ulong_t len, key_serial_t id2)
157 : : {
158 : 30 : print_keyring_serial_number(id1);
159 : 30 : tprints(", ");
160 : 30 : printstrn(tcp, addr, len);
161 : 30 : tprintf(", %llu, ", zero_extend_signed_to_ull(len));
162 : 30 : print_keyring_serial_number(id2);
163 : 30 : }
164 : :
165 : : static void
166 : 30 : keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
167 : : kernel_ulong_t addr, kernel_ulong_t len,
168 : : key_serial_t id2)
169 : : {
170 : 30 : print_keyring_serial_number(id1);
171 : 30 : tprints(", ");
172 : 30 : tprint_iov(tcp, len, addr, IOV_DECODE_STR);
173 : 30 : tprintf(", %llu, ", zero_extend_signed_to_ull(len));
174 : 30 : print_keyring_serial_number(id2);
175 : 30 : }
176 : :
177 : : static void
178 : 24 : keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
179 : : key_serial_t id2)
180 : : {
181 : 24 : print_keyring_serial_number(id1);
182 : 24 : tprintf(", %u, ", timeout);
183 : 24 : print_keyring_serial_number(id2);
184 : 24 : }
185 : :
186 : : static void
187 : 24 : keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
188 : : unsigned error, key_serial_t id2)
189 : : {
190 : 24 : const char *err_str = err_name(error);
191 : :
192 : 24 : print_keyring_serial_number(id1);
193 : 24 : tprintf(", %u, ", timeout);
194 : :
195 [ + + ]: 24 : if (err_str)
196 : 6 : tprintf("%s, ", err_str);
197 : : else
198 : 18 : tprintf("%u, ", error);
199 : :
200 : 24 : print_keyring_serial_number(id2);
201 : 24 : }
202 : :
203 : : static void
204 : 18 : keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout)
205 : : {
206 : 18 : print_keyring_serial_number(id);
207 : 18 : tprintf(", %u", timeout);
208 : 18 : }
209 : :
210 : : static void
211 : 18 : keyctl_get_persistent(struct tcb *tcp, unsigned uid, key_serial_t id)
212 : : {
213 : 18 : printuid("", uid);
214 : 18 : tprints(", ");
215 : 18 : print_keyring_serial_number(id);
216 : 18 : }
217 : :
218 : : #include "xlat/key_perms.h"
219 : :
220 : : static void
221 : 18 : keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm)
222 : : {
223 : 18 : print_keyring_serial_number(id);
224 : 18 : tprints(", ");
225 : 18 : printflags(key_perms, perm, "KEY_???");
226 : 18 : }
227 : :
228 : : static void
229 : 30 : print_dh_params(struct tcb *tcp, kernel_ulong_t addr)
230 : : {
231 : : struct keyctl_dh_params params;
232 : :
233 [ + + ]: 30 : if (umove_or_printaddr(tcp, addr, ¶ms))
234 : 12 : return;
235 : :
236 : 18 : tprints("{private=");
237 : 18 : print_keyring_serial_number(params.private);
238 : 18 : tprints(", prime=");
239 : 18 : print_keyring_serial_number(params.prime);
240 : 18 : tprints(", base=");
241 : 18 : print_keyring_serial_number(params.base);
242 : 18 : tprints("}");
243 : : }
244 : :
245 : : static void
246 : 60 : keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf,
247 : : kernel_ulong_t len)
248 : : {
249 [ + + ]: 60 : if (entering(tcp)) {
250 : 30 : print_dh_params(tcp, params);
251 : 30 : tprints(", ");
252 : : } else {
253 [ + - ]: 30 : if (syserror(tcp)) {
254 : 30 : printaddr(buf);
255 : : } else {
256 [ # # ]: 0 : kernel_ulong_t rval = (tcp->u_rval >= 0) &&
257 [ # # ]: 0 : ((kernel_ulong_t) tcp->u_rval > len) ? len :
258 : 0 : (kernel_ulong_t) tcp->u_rval;
259 : 0 : printstrn(tcp, buf, rval);
260 : : }
261 : 30 : tprintf(", %llu", zero_extend_signed_to_ull(len));
262 : : }
263 : 60 : }
264 : :
265 : : #include "xlat/key_reqkeys.h"
266 : : #include "xlat/keyctl_commands.h"
267 : :
268 : 666 : SYS_FUNC(keyctl)
269 : : {
270 : 666 : int cmd = tcp->u_arg[0];
271 : 666 : kernel_ulong_t arg2 = tcp->u_arg[1];
272 : 666 : kernel_ulong_t arg3 = tcp->u_arg[2];
273 : 666 : kernel_ulong_t arg4 = tcp->u_arg[3];
274 : 666 : kernel_ulong_t arg5 = tcp->u_arg[4];
275 : :
276 [ + + ]: 666 : if (entering(tcp)) {
277 : 546 : printxval(keyctl_commands, cmd, "KEYCTL_???");
278 : :
279 : : /*
280 : : * For now, KEYCTL_SESSION_TO_PARENT is the only cmd without
281 : : * arguments.
282 : : */
283 [ + + ]: 546 : if (cmd != KEYCTL_SESSION_TO_PARENT)
284 : 540 : tprints(", ");
285 : : }
286 : :
287 [ + + + + : 666 : switch (cmd) {
+ + + + +
+ + + + +
+ + + +
+ ]
288 : : case KEYCTL_GET_KEYRING_ID:
289 : 12 : keyctl_get_keyring_id(tcp, arg2, arg3);
290 : 12 : break;
291 : :
292 : : case KEYCTL_JOIN_SESSION_KEYRING:
293 : 30 : printstr(tcp, arg2);
294 : 30 : break;
295 : :
296 : : case KEYCTL_UPDATE:
297 : 24 : keyctl_update_key(tcp, arg2, arg3, arg4);
298 : 24 : break;
299 : :
300 : : case KEYCTL_REVOKE:
301 : : case KEYCTL_CLEAR:
302 : : case KEYCTL_INVALIDATE:
303 : : case KEYCTL_ASSUME_AUTHORITY:
304 : 96 : print_keyring_serial_number(arg2);
305 : 96 : break;
306 : :
307 : : case KEYCTL_LINK:
308 : : case KEYCTL_UNLINK:
309 : 36 : keyctl_handle_key_key(tcp, arg2, arg3);
310 : 36 : break;
311 : :
312 : : case KEYCTL_DESCRIBE:
313 : : case KEYCTL_READ:
314 : : case KEYCTL_GET_SECURITY:
315 : 180 : keyctl_read_key(tcp, arg2, arg3, arg4, cmd != KEYCTL_READ);
316 : 180 : return 0;
317 : :
318 : : case KEYCTL_SEARCH:
319 : 30 : keyctl_keyring_search(tcp, arg2, arg3, arg4, arg5);
320 : 30 : break;
321 : :
322 : : case KEYCTL_CHOWN:
323 : 12 : keyctl_chown_key(tcp, arg2, arg3, arg4);
324 : 12 : break;
325 : :
326 : : case KEYCTL_SETPERM:
327 : 18 : keyctl_setperm_key(tcp, arg2, arg3);
328 : 18 : break;
329 : :
330 : : case KEYCTL_INSTANTIATE:
331 : 30 : keyctl_instantiate_key(tcp, arg2, arg3, arg4, arg5);
332 : 30 : break;
333 : :
334 : : case KEYCTL_NEGATE:
335 : 24 : keyctl_negate_key(tcp, arg2, arg3, arg4);
336 : 24 : break;
337 : :
338 : : case KEYCTL_SET_REQKEY_KEYRING:
339 : 12 : printxval(key_reqkeys, arg2, "KEY_REQKEY_DEFL_???");
340 : 12 : break;
341 : :
342 : : case KEYCTL_SET_TIMEOUT:
343 : 18 : keyctl_set_timeout(tcp, arg2, arg3);
344 : 18 : break;
345 : :
346 : : case KEYCTL_SESSION_TO_PARENT:
347 : 6 : break;
348 : :
349 : : case KEYCTL_REJECT:
350 : 24 : keyctl_reject_key(tcp, arg2, arg3, arg4, arg5);
351 : 24 : break;
352 : :
353 : : case KEYCTL_INSTANTIATE_IOV:
354 : 30 : keyctl_instantiate_key_iov(tcp, arg2, arg3, arg4, arg5);
355 : 30 : break;
356 : :
357 : : case KEYCTL_GET_PERSISTENT:
358 : 18 : keyctl_get_persistent(tcp, arg2, arg3);
359 : 18 : break;
360 : :
361 : : case KEYCTL_DH_COMPUTE:
362 : 60 : keyctl_dh_compute(tcp, arg2, arg3, arg4);
363 : 60 : return 0;
364 : :
365 : : default:
366 : 6 : tprintf("%#" PRI_klx ", %#" PRI_klx
367 : : ", %#" PRI_klx ", %#" PRI_klx,
368 : : arg2, arg3, arg4, arg5);
369 : 6 : break;
370 : : }
371 : :
372 : 426 : return RVAL_DECODED;
373 : : }
|