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