1#include "defs.h"
2
3typedef int32_t key_serial_t;
4
5#include "xlat/key_spec.h"
6
7static void
8print_keyring_serial_number(key_serial_t id)
9{
10	const char *str = xlookup(key_spec, id);
11
12	if (str)
13		tprints(str);
14	else
15		tprintf("%d", id);
16}
17
18SYS_FUNC(add_key)
19{
20	if (entering(tcp)) {
21		/* type */
22		printstr(tcp, tcp->u_arg[0], -1);
23		/* description */
24		tprints(", ");
25		printstr(tcp, tcp->u_arg[1], -1);
26		/* payload */
27		tprints(", ");
28		printstr(tcp, tcp->u_arg[2], tcp->u_arg[3]);
29		/* payload length */
30		tprintf(", %lu, ", tcp->u_arg[3]);
31		/* keyring serial number */
32		print_keyring_serial_number(tcp->u_arg[4]);
33	}
34	return 0;
35}
36
37SYS_FUNC(request_key)
38{
39	if (entering(tcp)) {
40		/* type */
41		printstr(tcp, tcp->u_arg[0], -1);
42		/* description */
43		tprints(", ");
44		printstr(tcp, tcp->u_arg[1], -1);
45		/* callout_info */
46		tprints(", ");
47		printstr(tcp, tcp->u_arg[2], -1);
48		/* keyring serial number */
49		tprints(", ");
50		print_keyring_serial_number(tcp->u_arg[3]);
51	}
52	return 0;
53}
54
55static int
56keyctl_get_keyring_id(struct tcb *tcp, key_serial_t id, int create)
57{
58	if (entering(tcp)) {
59		tprints(", ");
60		print_keyring_serial_number(id);
61		tprintf(", %d", create);
62	}
63	return 0;
64}
65
66static int
67keyctl_join_session_keyring(struct tcb *tcp, long addr)
68{
69	if (entering(tcp)) {
70		tprints(", ");
71		printstr(tcp, addr, -1);
72	}
73	return 0;
74}
75
76static int
77keyctl_update_key(struct tcb *tcp, key_serial_t id, long addr, long len)
78{
79	if (entering(tcp)) {
80		tprints(", ");
81		print_keyring_serial_number(id);
82		tprints(", ");
83		printstr(tcp, addr, len);
84		tprintf(", %lu", len);
85	}
86	return 0;
87}
88
89static int
90keyctl_handle_key(struct tcb *tcp, key_serial_t id)
91{
92	if (entering(tcp)) {
93		tprints(", ");
94		print_keyring_serial_number(id);
95	}
96	return 0;
97}
98
99static int
100keyctl_handle_key_key(struct tcb *tcp, key_serial_t id1, key_serial_t id2)
101{
102	if (entering(tcp)) {
103		tprints(", ");
104		print_keyring_serial_number(id1);
105		tprints(", ");
106		print_keyring_serial_number(id2);
107	}
108	return 0;
109}
110
111static int
112keyctl_read_key(struct tcb *tcp, key_serial_t id, long addr, long len)
113{
114	if (entering(tcp)) {
115		tprints(", ");
116		print_keyring_serial_number(id);
117		tprints(", ");
118	} else {
119		if (addr && syserror(tcp))
120			tprintf("%#lx", addr);
121		else {
122			long rval = tcp->u_rval > len ?
123				    len : (tcp->u_rval ? -1 : 0);
124			printstr(tcp, addr, rval);
125		}
126		tprintf(", %lu", len);
127	}
128	return 0;
129}
130
131static int
132keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, long addr1,
133		      long addr2, key_serial_t id2)
134{
135	if (entering(tcp)) {
136		tprints(", ");
137		print_keyring_serial_number(id1);
138		tprints(", ");
139		printstr(tcp, addr1, -1);
140		tprints(", ");
141		printstr(tcp, addr2, -1);
142		tprints(", ");
143		print_keyring_serial_number(id2);
144	}
145	return 0;
146}
147
148static int
149keyctl_chown_key(struct tcb *tcp, key_serial_t id, int user, int group)
150{
151	if (entering(tcp)) {
152		tprints(", ");
153		print_keyring_serial_number(id);
154		tprintf(", %d, %d", user, group);
155	}
156	return 0;
157}
158
159static int
160keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, long addr,
161		       long len, key_serial_t id2)
162{
163	if (entering(tcp)) {
164		tprints(", ");
165		print_keyring_serial_number(id1);
166		tprints(", ");
167		printstr(tcp, addr, len);
168		tprintf(", %lu, ", len);
169		print_keyring_serial_number(id2);
170	}
171	return 0;
172}
173
174static int
175keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
176			   long addr, long len, key_serial_t id2)
177{
178	if (entering(tcp)) {
179		tprints(", ");
180		print_keyring_serial_number(id1);
181		tprints(", ");
182		tprint_iov(tcp, len, addr, 1);
183		tprintf(", %lu, ", len);
184		print_keyring_serial_number(id2);
185	}
186	return 0;
187}
188
189static int
190keyctl_negate_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
191		  key_serial_t id2)
192{
193	if (entering(tcp)) {
194		tprints(", ");
195		print_keyring_serial_number(id1);
196		tprintf(", %u, ", timeout);
197		print_keyring_serial_number(id2);
198	}
199	return 0;
200}
201
202static int
203keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
204		  unsigned error, key_serial_t id2)
205{
206	if (entering(tcp)) {
207		tprints(", ");
208		print_keyring_serial_number(id1);
209		tprintf(", %u, %u, ", timeout, error);
210		print_keyring_serial_number(id2);
211	}
212	return 0;
213}
214
215static int
216keyctl_set_timeout(struct tcb *tcp, key_serial_t id, unsigned timeout)
217{
218	if (entering(tcp)) {
219		tprints(", ");
220		print_keyring_serial_number(id);
221		tprintf(", %u", timeout);
222	}
223	return 0;
224}
225
226static int
227keyctl_get_persistent(struct tcb *tcp, int uid, key_serial_t id)
228{
229	if (entering(tcp)) {
230		tprintf(", %d, ", uid);
231		print_keyring_serial_number(id);
232	}
233	return 0;
234}
235
236#include "xlat/key_perms.h"
237
238static int
239keyctl_setperm_key(struct tcb *tcp, key_serial_t id, uint32_t perm)
240{
241	if (entering(tcp)) {
242		tprints(", ");
243		print_keyring_serial_number(id);
244		tprints(", ");
245		printflags(key_perms, perm, "KEY_???");
246	}
247	return 0;
248}
249
250#include "xlat/key_reqkeys.h"
251
252static int
253keyctl_set_reqkey_keyring(struct tcb *tcp, int reqkey)
254{
255	if (entering(tcp)) {
256		tprints(", ");
257		printxval(key_reqkeys, reqkey, "KEY_REQKEY_DEFL_???");
258	}
259	return 0;
260}
261
262#include "xlat/keyctl_commands.h"
263
264SYS_FUNC(keyctl)
265{
266	int cmd = tcp->u_arg[0];
267
268	if (entering(tcp))
269		printxval(keyctl_commands, cmd, "KEYCTL_???");
270
271	switch (cmd) {
272	case KEYCTL_GET_KEYRING_ID:
273		return keyctl_get_keyring_id(tcp, tcp->u_arg[1], tcp->u_arg[2]);
274
275	case KEYCTL_JOIN_SESSION_KEYRING:
276		return keyctl_join_session_keyring(tcp, tcp->u_arg[1]);
277
278	case KEYCTL_UPDATE:
279		return keyctl_update_key(tcp, tcp->u_arg[1],
280					 tcp->u_arg[2], tcp->u_arg[3]);
281
282	case KEYCTL_REVOKE:
283	case KEYCTL_CLEAR:
284	case KEYCTL_INVALIDATE:
285	case KEYCTL_ASSUME_AUTHORITY:
286		return keyctl_handle_key(tcp, tcp->u_arg[1]);
287
288	case KEYCTL_LINK:
289	case KEYCTL_UNLINK:
290		return keyctl_handle_key_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
291
292	case KEYCTL_DESCRIBE:
293	case KEYCTL_READ:
294	case KEYCTL_GET_SECURITY:
295		return keyctl_read_key(tcp, tcp->u_arg[1],
296				       tcp->u_arg[2], tcp->u_arg[3]);
297
298	case KEYCTL_SEARCH:
299		return keyctl_keyring_search(tcp, tcp->u_arg[1], tcp->u_arg[2],
300					     tcp->u_arg[3], tcp->u_arg[4]);
301
302	case KEYCTL_CHOWN:
303		return keyctl_chown_key(tcp, tcp->u_arg[1],
304					tcp->u_arg[2], tcp->u_arg[3]);
305
306	case KEYCTL_SETPERM:
307		return keyctl_setperm_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
308
309	case KEYCTL_INSTANTIATE:
310		return keyctl_instantiate_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
311					      tcp->u_arg[3], tcp->u_arg[4]);
312
313	case KEYCTL_NEGATE:
314		return keyctl_negate_key(tcp, tcp->u_arg[1],
315					 tcp->u_arg[2], tcp->u_arg[3]);
316
317	case KEYCTL_SET_REQKEY_KEYRING:
318		return keyctl_set_reqkey_keyring(tcp, tcp->u_arg[1]);
319
320	case KEYCTL_SET_TIMEOUT:
321		return keyctl_set_timeout(tcp, tcp->u_arg[1], tcp->u_arg[2]);
322
323	case KEYCTL_SESSION_TO_PARENT:
324		return 0;
325
326	case KEYCTL_REJECT:
327		return keyctl_reject_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
328					 tcp->u_arg[3], tcp->u_arg[4]);
329
330	case KEYCTL_INSTANTIATE_IOV:
331		return keyctl_instantiate_key_iov(tcp, tcp->u_arg[1],
332						  tcp->u_arg[2], tcp->u_arg[3],
333						  tcp->u_arg[4]);
334
335	case KEYCTL_GET_PERSISTENT:
336		return keyctl_get_persistent(tcp, tcp->u_arg[1], tcp->u_arg[2]);
337
338	default:
339		if (entering(tcp))
340			tprintf(", %#lx, %#lx, %#lx, %#lx",
341				tcp->u_arg[1], tcp->u_arg[2],
342				tcp->u_arg[3], tcp->u_arg[4]);
343	}
344
345	return 0;
346}
347