blob: fa4b7f58e1580ceb939fa8476ec6806f6f7e2acc [file] [log] [blame]
Dmitry V. Levin3acf4032014-02-05 22:41:45 +00001#include "defs.h"
2#include <linux/keyctl.h>
3
4typedef int32_t key_serial_t;
5
6static const struct xlat key_spec[] = {
7 XLAT(KEY_SPEC_THREAD_KEYRING),
8 XLAT(KEY_SPEC_PROCESS_KEYRING),
9 XLAT(KEY_SPEC_SESSION_KEYRING),
10 XLAT(KEY_SPEC_USER_KEYRING),
11 XLAT(KEY_SPEC_USER_SESSION_KEYRING),
12 XLAT(KEY_SPEC_GROUP_KEYRING),
13 XLAT(KEY_SPEC_REQKEY_AUTH_KEY),
14 XLAT(KEY_SPEC_REQUESTOR_KEYRING),
15 XLAT_END
16};
17
18static void
19print_keyring_serial_number(key_serial_t id)
20{
21 const char *str = xlookup(key_spec, id);
22
23 if (str)
24 tprints(str);
25 else
26 tprintf("%d", id);
27}
28
29int
30sys_add_key(struct tcb *tcp)
31{
32 if (entering(tcp)) {
33 /* type */
34 printstr(tcp, tcp->u_arg[0], -1);
35 /* description */
36 tprints(", ");
37 printstr(tcp, tcp->u_arg[1], -1);
38 /* payload */
39 tprints(", ");
40 printstr(tcp, tcp->u_arg[2], tcp->u_arg[3]);
41 /* payload length */
42 tprintf(", %lu, ", tcp->u_arg[3]);
43 /* keyring serial number */
44 print_keyring_serial_number(tcp->u_arg[4]);
45 }
46 return 0;
47}
48
49int
50sys_request_key(struct tcb *tcp)
51{
52 if (entering(tcp)) {
53 /* type */
54 printstr(tcp, tcp->u_arg[0], -1);
55 /* description */
56 tprints(", ");
57 printstr(tcp, tcp->u_arg[1], -1);
58 /* callout_info */
59 tprints(", ");
60 printstr(tcp, tcp->u_arg[2], -1);
61 /* keyring serial number */
62 tprints(", ");
63 print_keyring_serial_number(tcp->u_arg[3]);
64 }
65 return 0;
66}
67
68static int
69keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create)
70{
71 if (entering(tcp)) {
72 tprints(", ");
73 print_keyring_serial_number(id);
74 tprintf(", %d", create);
75 }
76 return 0;
77}
78
79static int
80keyctl_join_session_keyring(struct tcb *tcp, long addr)
81{
82 if (entering(tcp)) {
83 tprints(", ");
84 printstr(tcp, addr, -1);
85 }
86 return 0;
87}
88
89static int
90keyctl_update_key(struct tcb *tcp, key_serial_t id, long addr, long len)
91{
92 if (entering(tcp)) {
93 tprints(", ");
94 print_keyring_serial_number(id);
95 tprints(", ");
96 printstr(tcp, addr, len);
97 tprintf(", %lu", len);
98 }
99 return 0;
100}
101
102static int
103keyctl_handle_key(struct tcb *tcp, key_serial_t id)
104{
105 if (entering(tcp)) {
106 tprints(", ");
107 print_keyring_serial_number(id);
108 }
109 return 0;
110}
111
112static int
113keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2)
114{
115 if (entering(tcp)) {
116 tprints(", ");
117 print_keyring_serial_number(id1);
118 tprints(", ");
119 print_keyring_serial_number(id2);
120 }
121 return 0;
122}
123
124static int
125keyctl_read_key(struct tcb *tcp, key_serial_t id, long addr, long len)
126{
127 if (entering(tcp)) {
128 tprints(", ");
129 print_keyring_serial_number(id);
130 tprints(", ");
131 } else {
132 if (addr && syserror(tcp))
133 tprintf("%#lx", addr);
134 else {
135 long rval = tcp->u_rval > len ?
136 len : (tcp->u_rval ? -1 : 0);
137 printstr(tcp, addr, rval);
138 }
139 tprintf(", %lu", len);
140 }
141 return 0;
142}
143
144static int
145keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, long addr1,
146 long addr2, key_serial_t id2)
147{
148 if (entering(tcp)) {
149 tprints(", ");
150 print_keyring_serial_number(id1);
151 tprints(", ");
152 printstr(tcp, addr1, -1);
153 tprints(", ");
154 printstr(tcp, addr2, -1);
155 tprints(", ");
156 print_keyring_serial_number(id2);
157 }
158 return 0;
159}
160
161static int
162keyctl_chown_key(struct tcb *tcp, key_serial_t id, int user, int group)
163{
164 if (entering(tcp)) {
165 tprints(", ");
166 print_keyring_serial_number(id);
167 tprintf(", %d, %d", user, group);
168 }
169 return 0;
170}
171
172static int
173keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, long addr,
174 long len, key_serial_t id2)
175{
176 if (entering(tcp)) {
177 tprints(", ");
178 print_keyring_serial_number(id1);
179 tprints(", ");
180 printstr(tcp, addr, len);
181 tprintf(", %lu, ", len);
182 print_keyring_serial_number(id2);
183 }
184 return 0;
185}
186
187static int
188keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
189 long addr, long len, key_serial_t id2)
190{
191 if (entering(tcp)) {
192 tprints(", ");
193 print_keyring_serial_number(id1);
194 tprints(", ");
195 tprint_iov(tcp, len, addr, 1);
196 tprintf(", %lu, ", len);
197 print_keyring_serial_number(id2);
198 }
199 return 0;
200}
201
202static int
203keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
204 key_serial_t id2)
205{
206 if (entering(tcp)) {
207 tprints(", ");
208 print_keyring_serial_number(id1);
209 tprintf(", %u, ", timeout);
210 print_keyring_serial_number(id2);
211 }
212 return 0;
213}
214
215static int
216keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
217 unsigned error, key_serial_t id2)
218{
219 if (entering(tcp)) {
220 tprints(", ");
221 print_keyring_serial_number(id1);
222 tprintf(", %u, %u, ", timeout, error);
223 print_keyring_serial_number(id2);
224 }
225 return 0;
226}
227
228static int
229keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout)
230{
231 if (entering(tcp)) {
232 tprints(", ");
233 print_keyring_serial_number(id);
234 tprintf(", %u", timeout);
235 }
236 return 0;
237}
238
239static int
240keyctl_get_persistent(struct tcb *tcp, int uid, key_serial_t id)
241{
242 if (entering(tcp)) {
243 tprintf(", %d, ", uid);
244 print_keyring_serial_number(id);
245 }
246 return 0;
247}
248
249#define KEY_POS_VIEW 0x01000000
250#define KEY_POS_READ 0x02000000
251#define KEY_POS_WRITE 0x04000000
252#define KEY_POS_SEARCH 0x08000000
253#define KEY_POS_LINK 0x10000000
254#define KEY_POS_SETATTR 0x20000000
255#define KEY_POS_ALL 0x3f000000
256#define KEY_USR_VIEW 0x00010000
257#define KEY_USR_READ 0x00020000
258#define KEY_USR_WRITE 0x00040000
259#define KEY_USR_SEARCH 0x00080000
260#define KEY_USR_LINK 0x00100000
261#define KEY_USR_SETATTR 0x00200000
262#define KEY_USR_ALL 0x003f0000
263#define KEY_GRP_VIEW 0x00000100
264#define KEY_GRP_READ 0x00000200
265#define KEY_GRP_WRITE 0x00000400
266#define KEY_GRP_SEARCH 0x00000800
267#define KEY_GRP_LINK 0x00001000
268#define KEY_GRP_SETATTR 0x00002000
269#define KEY_GRP_ALL 0x00003f00
270#define KEY_OTH_VIEW 0x00000001
271#define KEY_OTH_READ 0x00000002
272#define KEY_OTH_WRITE 0x00000004
273#define KEY_OTH_SEARCH 0x00000008
274#define KEY_OTH_LINK 0x00000010
275#define KEY_OTH_SETATTR 0x00000020
276#define KEY_OTH_ALL 0x0000003f
277
278static const struct xlat key_perms[] = {
279 XLAT(KEY_POS_VIEW),
280 XLAT(KEY_POS_READ),
281 XLAT(KEY_POS_WRITE),
282 XLAT(KEY_POS_SEARCH),
283 XLAT(KEY_POS_LINK),
284 XLAT(KEY_POS_SETATTR),
285 XLAT(KEY_POS_ALL),
286 XLAT(KEY_USR_VIEW),
287 XLAT(KEY_USR_READ),
288 XLAT(KEY_USR_WRITE),
289 XLAT(KEY_USR_SEARCH),
290 XLAT(KEY_USR_LINK),
291 XLAT(KEY_USR_SETATTR),
292 XLAT(KEY_USR_ALL),
293 XLAT(KEY_GRP_VIEW),
294 XLAT(KEY_GRP_READ),
295 XLAT(KEY_GRP_WRITE),
296 XLAT(KEY_GRP_SEARCH),
297 XLAT(KEY_GRP_LINK),
298 XLAT(KEY_GRP_SETATTR),
299 XLAT(KEY_GRP_ALL),
300 XLAT(KEY_OTH_VIEW),
301 XLAT(KEY_OTH_READ),
302 XLAT(KEY_OTH_WRITE),
303 XLAT(KEY_OTH_SEARCH),
304 XLAT(KEY_OTH_LINK),
305 XLAT(KEY_OTH_SETATTR),
306 XLAT(KEY_OTH_ALL),
307 XLAT_END
308};
309
310static int
311keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm)
312{
313 if (entering(tcp)) {
314 tprints(", ");
315 print_keyring_serial_number(id);
316 tprints(", ");
317 printflags(key_perms, perm, "KEY_???");
318 }
319 return 0;
320}
321
322static const struct xlat key_reqkeys[] = {
323 XLAT(KEY_REQKEY_DEFL_NO_CHANGE),
324 XLAT(KEY_REQKEY_DEFL_DEFAULT),
325 XLAT(KEY_REQKEY_DEFL_THREAD_KEYRING),
326 XLAT(KEY_REQKEY_DEFL_PROCESS_KEYRING),
327 XLAT(KEY_REQKEY_DEFL_SESSION_KEYRING),
328 XLAT(KEY_REQKEY_DEFL_USER_KEYRING),
329 XLAT(KEY_REQKEY_DEFL_USER_SESSION_KEYRING),
330 XLAT(KEY_REQKEY_DEFL_GROUP_KEYRING),
331 XLAT(KEY_REQKEY_DEFL_REQUESTOR_KEYRING),
332 XLAT_END
333};
334
335static int
336keyctl_set_reqkey_keyring(struct tcb *tcp, int reqkey)
337{
338 if (entering(tcp)) {
339 tprints(", ");
340 printxval(key_reqkeys, reqkey, "KEY_REQKEY_DEFL_???");
341 }
342 return 0;
343}
344
345static const struct xlat keyctl_commands[] = {
346 XLAT(KEYCTL_GET_KEYRING_ID),
347 XLAT(KEYCTL_JOIN_SESSION_KEYRING),
348 XLAT(KEYCTL_UPDATE),
349 XLAT(KEYCTL_REVOKE),
350 XLAT(KEYCTL_CHOWN),
351 XLAT(KEYCTL_SETPERM),
352 XLAT(KEYCTL_DESCRIBE),
353 XLAT(KEYCTL_CLEAR),
354 XLAT(KEYCTL_LINK),
355 XLAT(KEYCTL_UNLINK),
356 XLAT(KEYCTL_SEARCH),
357 XLAT(KEYCTL_READ),
358 XLAT(KEYCTL_INSTANTIATE),
359 XLAT(KEYCTL_NEGATE),
360 XLAT(KEYCTL_SET_REQKEY_KEYRING),
361 XLAT(KEYCTL_SET_TIMEOUT),
362 XLAT(KEYCTL_ASSUME_AUTHORITY),
363 XLAT(KEYCTL_GET_SECURITY),
364 XLAT(KEYCTL_SESSION_TO_PARENT),
365 XLAT(KEYCTL_REJECT),
366 XLAT(KEYCTL_INSTANTIATE_IOV),
367 XLAT(KEYCTL_INVALIDATE),
368 XLAT(KEYCTL_GET_PERSISTENT),
369 XLAT_END
370};
371
372int
373sys_keyctl(struct tcb *tcp)
374{
375 int cmd = tcp->u_arg[0];
376
377 if (entering(tcp))
378 printxval(keyctl_commands, cmd, "KEYCTL_???");
379
380 switch (cmd) {
381 case KEYCTL_GET_KEYRING_ID:
382 return keyctl_get_keyring_id(tcp, tcp->u_arg[1], tcp->u_arg[2]);
383
384 case KEYCTL_JOIN_SESSION_KEYRING:
385 return keyctl_join_session_keyring(tcp, tcp->u_arg[1]);
386
387 case KEYCTL_UPDATE:
388 return keyctl_update_key(tcp, tcp->u_arg[1],
389 tcp->u_arg[2], tcp->u_arg[3]);
390
391 case KEYCTL_REVOKE:
392 case KEYCTL_CLEAR:
393 case KEYCTL_INVALIDATE:
394 case KEYCTL_ASSUME_AUTHORITY:
395 return keyctl_handle_key(tcp, tcp->u_arg[1]);
396
397 case KEYCTL_LINK:
398 case KEYCTL_UNLINK:
399 return keyctl_handle_key_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
400
401 case KEYCTL_DESCRIBE:
402 case KEYCTL_READ:
403 case KEYCTL_GET_SECURITY:
404 return keyctl_read_key(tcp, tcp->u_arg[1],
405 tcp->u_arg[2], tcp->u_arg[3]);
406
407 case KEYCTL_SEARCH:
408 return keyctl_keyring_search(tcp, tcp->u_arg[1], tcp->u_arg[2],
409 tcp->u_arg[3], tcp->u_arg[4]);
410
411 case KEYCTL_CHOWN:
412 return keyctl_chown_key(tcp, tcp->u_arg[1],
413 tcp->u_arg[2], tcp->u_arg[3]);
414
415 case KEYCTL_SETPERM:
416 return keyctl_setperm_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
417
418 case KEYCTL_INSTANTIATE:
419 return keyctl_instantiate_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
420 tcp->u_arg[3], tcp->u_arg[4]);
421
422 case KEYCTL_NEGATE:
423 return keyctl_negate_key(tcp, tcp->u_arg[1],
424 tcp->u_arg[2], tcp->u_arg[3]);
425
426 case KEYCTL_SET_REQKEY_KEYRING:
427 return keyctl_set_reqkey_keyring(tcp, tcp->u_arg[1]);
428
429 case KEYCTL_SET_TIMEOUT:
430 return keyctl_set_timeout(tcp, tcp->u_arg[1], tcp->u_arg[2]);
431
432 case KEYCTL_SESSION_TO_PARENT:
433 return 0;
434
435 case KEYCTL_REJECT:
436 return keyctl_reject_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
437 tcp->u_arg[3], tcp->u_arg[4]);
438
439 case KEYCTL_INSTANTIATE_IOV:
440 return keyctl_instantiate_key_iov(tcp, tcp->u_arg[1],
441 tcp->u_arg[2], tcp->u_arg[3],
442 tcp->u_arg[4]);
443
444 case KEYCTL_GET_PERSISTENT:
445 return keyctl_get_persistent(tcp, tcp->u_arg[1], tcp->u_arg[2]);
446
447 default:
448 if (entering(tcp))
449 tprintf(", %#lx, %#lx, %#lx, %#lx",
450 tcp->u_arg[1], tcp->u_arg[2],
451 tcp->u_arg[3], tcp->u_arg[4]);
452 }
453
454 return 0;
455}