• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Check decoding of keyctl syscall.
3  *
4  * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "tests.h"
31 
32 #include <asm/unistd.h>
33 
34 #ifdef __NR_keyctl
35 
36 # include <linux/types.h>
37 # include <linux/keyctl.h>
38 
39 # include <errno.h>
40 # include <inttypes.h>
41 # include <stdarg.h>
42 # include <stdbool.h>
43 # include <stdio.h>
44 # include <stdlib.h>
45 # include <string.h>
46 # include <unistd.h>
47 # include <sys/uio.h>
48 
49 /* This check should be before #include "xlat/keyctl_commands.h" */
50 # ifndef KEYCTL_DH_COMPUTE
51 struct keyctl_dh_params {
52 	int32_t private;
53 	int32_t prime;
54 	int32_t base;
55 };
56 # endif
57 
58 # include "xlat.h"
59 # include "xlat/keyctl_commands.h"
60 
61 # ifndef KEY_SPEC_REQKEY_AUTH_KEY
62 #  define KEY_SPEC_REQKEY_AUTH_KEY   -7
63 # endif
64 
65 # ifndef KEY_SPEC_REQUESTOR_KEYRING
66 #  define KEY_SPEC_REQUESTOR_KEYRING -8
67 # endif
68 
69 static const size_t limit = 10;
70 
71 /*
72  * Well, this is true for DESCRIBE and GET_SECURITY, and false for READ and
73  * DH_COMPUTE and I see no ability to pass this information without
74  * significantly breaking interface.
75  */
76 bool nul_terminated_buf = true;
77 bool buf_in_arg;
78 
79 /*
80  * When this is called with positive size, the buffer provided is an "out"
81  * argument and rc contains resulting size (globally defined nul_terminated_buf
82  * controls whether it is nul-terminated or not). If size is negative,
83  * it contains "in" argument.
84  */
85 void
print_quoted_string_limit(const char * str,size_t size,long rc)86 print_quoted_string_limit(const char *str, size_t size, long rc)
87 {
88 	size_t print_size = ((rc >= 0) && (size > 0)) ?
89 		((unsigned long) rc > size ? size :
90 		(unsigned long) rc) : size;
91 	size_t limited_size = print_size > limit ? limit : print_size;
92 
93 	if ((rc == -1) && !buf_in_arg) {
94 		printf("%p", str);
95 		return;
96 	}
97 
98 	if (!nul_terminated_buf ||
99 	    (strnlen(str, limited_size) == limited_size)) {
100 		printf("\"");
101 		print_quoted_memory(str, limited_size);
102 		if (print_size > limit)
103 			printf("\"...");
104 		else
105 			printf("\"");
106 	} else {
107 		printf("\"");
108 		print_quoted_string(str);
109 		printf("\"");
110 	}
111 }
112 
113 static void
print_arg(kernel_ulong_t arg,const char * str,const char * fmt,size_t size,long rc)114 print_arg(kernel_ulong_t arg, const char *str, const char *fmt, size_t size,
115 	long rc)
116 {
117 	if (size == (size_t) -1)
118 		size = 0;
119 
120 	if (str) {
121 		printf("%s", str);
122 	} else {
123 		if (size == sizeof(uint64_t))
124 			printf(fmt, (uint64_t)arg);
125 		else if (size == sizeof(uint32_t))
126 			printf(fmt, (uint32_t)arg);
127 		else
128 			print_quoted_string_limit((void *) (uintptr_t) arg,
129 						  size, rc);
130 	}
131 }
132 
133 /*
134  * Arguments are passed as sz, val, str, fmt. Arguments are read until 4
135  * arguments are retrieved or size of 0 is occurred.
136  *
137  * str == NULL && fmt == NULL && sz not in {4, 8} - print_quoted_string_limit is
138  *   used for argument printing. If sz is negative, in argument is assumed, out
139  *   otherwise.
140  */
141 void
do_keyctl(kernel_ulong_t cmd,const char * cmd_str,...)142 do_keyctl(kernel_ulong_t cmd, const char *cmd_str, ...)
143 {
144 	kernel_ulong_t args[4] = {
145 		(kernel_ulong_t) 0xdeadfee1badc0de5ULL,
146 		(kernel_ulong_t) 0xdeadfee2badc0de6ULL,
147 		(kernel_ulong_t) 0xdeadfee3badc0de7ULL,
148 		(kernel_ulong_t) 0xdeadfee4badc0de8ULL,
149 	};
150 	const char *arg_str[4] = { NULL };
151 	const char *arg_fmt[4] = { "%llu", "%llu", "%llu", "%llu" };
152 	size_t arg_sz[4] = {
153 		sizeof(kernel_ulong_t),
154 		sizeof(kernel_ulong_t),
155 		sizeof(kernel_ulong_t),
156 		sizeof(kernel_ulong_t),
157 	};
158 	unsigned i;
159 	unsigned cnt = 0;
160 
161 	va_list ap;
162 
163 	va_start(ap, cmd_str);
164 
165 	do {
166 		arg_sz[cnt] = va_arg(ap, size_t);
167 		if (!arg_sz[cnt])
168 			break;
169 
170 		if (arg_sz[cnt] == sizeof(uint64_t))
171 			args[cnt] = va_arg(ap, uint64_t);
172 		else if (arg_sz[cnt] == sizeof(uint32_t))
173 			args[cnt] = va_arg(ap, uint32_t);
174 		else
175 			args[cnt] = (uintptr_t) va_arg(ap, void *);
176 
177 		arg_str[cnt] = va_arg(ap, char *);
178 		arg_fmt[cnt] = va_arg(ap, char *);
179 	} while (++cnt < 4);
180 
181 	long rc = syscall(__NR_keyctl, cmd, args[0], args[1], args[2], args[3]);
182 	const char *errstr = sprintrc(rc);
183 	printf("keyctl(%s", cmd_str);
184 	for (i = 0; i < cnt; i++) {
185 		printf(", ");
186 		print_arg(args[i], arg_str[i], arg_fmt[i], arg_sz[i], rc);
187 	}
188 	printf(") = %s\n", errstr);
189 }
190 
191 int
main(void)192 main(void)
193 {
194 	enum { PR_LIMIT = 10, IOV_SIZE = 11, IOV_STR_SIZE = 4096 };
195 
196 	static const char *kulong_fmt =
197 		sizeof(kernel_ulong_t) == sizeof(uint64_t) ? "%#llx" : "%#x";
198 	static const char *ksize_fmt =
199 		sizeof(kernel_ulong_t) == sizeof(uint64_t) ? "%llu" : "%u";
200 	static const char *ptr_fmt =
201 		sizeof(void *) == sizeof(uint64_t) ? "%#llx" : "%#x";
202 	static const char unterminated1[] = { '\1', '\2', '\3', '\4', '\5' };
203 	static const char unterminated2[] = { '\6', '\7', '\10', '\11', '\12' };
204 	static const char short_type_str[] = "shrt type";
205 	static const char short_desc_str[] = "shrt desc";
206 	static const char long_type_str[] = "overly long key type";
207 	static const char long_desc_str[] = "overly long key description";
208 	static const int32_t bogus_key1 = 0xdeadf00d;
209 	static const int32_t bogus_key2 = 0x1eefdead;
210 	static const kernel_ulong_t bogus_key3 =
211 		(kernel_ulong_t) 0xdec0ded1dec0ded2ULL;
212 	static const char *bogus_key3_str = "-557785390";
213 
214 	static const struct keyctl_dh_params kcdhp_data = {
215 		KEY_SPEC_GROUP_KEYRING, 1234567890, 3141592653U };
216 	static const char *kcdhp_str = "{private=KEY_SPEC_GROUP_KEYRING, "
217 		"prime=1234567890, base=-1153374643}";
218 
219 	char *bogus_str = tail_memdup(unterminated1, sizeof(unterminated1));
220 	char *bogus_desc = tail_memdup(unterminated2, sizeof(unterminated2));
221 	char *short_type = tail_memdup(short_type_str, sizeof(short_type_str));
222 	char *short_desc = tail_memdup(short_desc_str, sizeof(short_desc_str));
223 	char *long_type = tail_memdup(long_type_str, sizeof(long_type_str));
224 	char *long_desc = tail_memdup(long_desc_str, sizeof(long_desc_str));
225 	char *kcdhp = tail_memdup(&kcdhp_data, sizeof(kcdhp_data));
226 	struct iovec *key_iov = tail_alloc(sizeof(*key_iov) * IOV_SIZE);
227 	char *bogus_buf1 = tail_alloc(9);
228 	char *bogus_buf2 = tail_alloc(256);
229 	char *key_iov_str1;
230 	char *key_iov_str2 = tail_alloc(4096);
231 	ssize_t ret;
232 	ssize_t kis_size = 0;
233 	int i;
234 
235 	key_iov[0].iov_base = short_type;
236 	key_iov[0].iov_len = sizeof(short_type_str);
237 	key_iov[1].iov_base = long_type;
238 	key_iov[1].iov_len = sizeof(long_type_str);
239 	key_iov[2].iov_base = short_desc;
240 	key_iov[2].iov_len = sizeof(short_desc_str);
241 	key_iov[3].iov_base = long_desc;
242 	key_iov[3].iov_len = sizeof(long_desc_str);
243 	key_iov[4].iov_base = bogus_str;
244 	key_iov[4].iov_len = 32;
245 
246 	for (i = 5; i < IOV_SIZE; i++) {
247 		key_iov[i].iov_base =
248 			(void *) (uintptr_t) (0xfffffacefffff00dULL +
249 			0x100000001ULL * i);
250 		key_iov[i].iov_len = (size_t) (0xcaffeeeddefaced7ULL +
251 			0x100000001ULL * i);
252 	}
253 
254 	ret = asprintf(&key_iov_str1, "[{iov_base=%p, iov_len=%zu}, "
255 		       "{iov_base=%p, iov_len=%zu}, "
256 		       "{iov_base=%p, iov_len=%zu}, "
257 		       "{iov_base=%p, iov_len=%zu}]",
258 		       key_iov[IOV_SIZE - 4].iov_base,
259 		       key_iov[IOV_SIZE - 4].iov_len,
260 		       key_iov[IOV_SIZE - 3].iov_base,
261 		       key_iov[IOV_SIZE - 3].iov_len,
262 		       key_iov[IOV_SIZE - 2].iov_base,
263 		       key_iov[IOV_SIZE - 2].iov_len,
264 		       key_iov[IOV_SIZE - 1].iov_base,
265 		       key_iov[IOV_SIZE - 1].iov_len);
266 
267 	if (ret < 0)
268 		error_msg_and_fail("asprintf");
269 
270 	ret = snprintf(key_iov_str2, IOV_STR_SIZE,
271 		       "[{iov_base=\"%s\\0\", iov_len=%zu}, "
272 		       "{iov_base=\"%.10s\"..., iov_len=%zu}, "
273 		       "{iov_base=\"%s\\0\", iov_len=%zu}, "
274 		       "{iov_base=\"%.10s\"..., iov_len=%zu}, ",
275 		       (char *) key_iov[0].iov_base, key_iov[0].iov_len,
276 		       (char *) key_iov[1].iov_base, key_iov[1].iov_len,
277 		       (char *) key_iov[2].iov_base, key_iov[2].iov_len,
278 		       (char *) key_iov[3].iov_base, key_iov[3].iov_len);
279 
280 	if ((ret < 0) || (ret >= IOV_STR_SIZE))
281 		error_msg_and_fail("snprintf");
282 
283 	for (i = 4; i < PR_LIMIT; i++) {
284 		kis_size += ret;
285 
286 		ret = snprintf(key_iov_str2 + kis_size, IOV_STR_SIZE - kis_size,
287 			       "{iov_base=%p, iov_len=%zu}, ",
288 			       key_iov[i].iov_base, key_iov[i].iov_len);
289 
290 		if ((ret < 0) || (ret >= (IOV_STR_SIZE - kis_size)))
291 			error_msg_and_fail("snprintf");
292 	}
293 
294 	kis_size += ret;
295 	snprintf(key_iov_str2 + kis_size, IOV_STR_SIZE - kis_size, "...]");
296 
297 
298 	/* Invalid command */
299 	do_keyctl((kernel_ulong_t) 0xbadc0dedfacefeedULL,
300 		  "0xfacefeed /* KEYCTL_??? */",
301 		  sizeof(kernel_ulong_t),
302 		  (kernel_ulong_t) 0xdeadfee1badc0de5ULL, NULL, kulong_fmt,
303 		  sizeof(kernel_ulong_t),
304 		  (kernel_ulong_t) 0xdeadfee2badc0de6ULL, NULL, kulong_fmt,
305 		  sizeof(kernel_ulong_t),
306 		  (kernel_ulong_t) 0xdeadfee3badc0de7ULL, NULL, kulong_fmt,
307 		  sizeof(kernel_ulong_t),
308 		  (kernel_ulong_t) 0xdeadfee4badc0de8ULL, NULL, kulong_fmt);
309 
310 
311 	/* GET_KEYRING_ID */
312 	do_keyctl(ARG_STR(KEYCTL_GET_KEYRING_ID),
313 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
314 		  sizeof(kernel_ulong_t),
315 		  (kernel_ulong_t) 0xbadc0dedffffffffLLU, "-1",
316 		  NULL, 0UL);
317 	do_keyctl(ARG_STR(KEYCTL_GET_KEYRING_ID),
318 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), "%d",
319 		  sizeof(int), 3141592653U, NULL, "%d",
320 		  NULL, 0UL);
321 
322 
323 	/* KEYCTL_JOIN_SESSION_KEYRING */
324 	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
325 		  sizeof(char *), ARG_STR(NULL), NULL, 0UL);
326 	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
327 		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
328 		  0UL);
329 	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
330 		  sizeof(char *), bogus_str, NULL, ptr_fmt, 0UL);
331 	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
332 		  sizeof(char *), ARG_STR("bogus name"), NULL, 0UL);
333 	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
334 		  sizeof(char *), "very long keyring name", "\"very long \"...",
335 		  NULL, 0UL);
336 
337 
338 	/* KEYCTL_UPDATE */
339 
340 	buf_in_arg = true;
341 
342 	do_keyctl(ARG_STR(KEYCTL_UPDATE),
343 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
344 		  sizeof(char *), ARG_STR(NULL), NULL,
345 		  sizeof(kernel_ulong_t),
346 		  (kernel_ulong_t) 0, NULL, ksize_fmt, 0UL);
347 	do_keyctl(ARG_STR(KEYCTL_UPDATE),
348 		  sizeof(int32_t), bogus_key1, NULL, "%d",
349 		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
350 		  sizeof(kernel_ulong_t),
351 		  (kernel_ulong_t) 0xdeadfee4badc0de8ULL, NULL, ksize_fmt,
352 		  0UL);
353 	do_keyctl(ARG_STR(KEYCTL_UPDATE),
354 		  sizeof(int32_t), bogus_key2, NULL, "%d",
355 		  sizeof(char *), bogus_str, NULL, ptr_fmt,
356 		  sizeof(kernel_ulong_t),
357 		  (kernel_ulong_t) 0xdeadfee4badc0de8ULL, NULL, ksize_fmt,
358 		  0UL);
359 	do_keyctl(ARG_STR(KEYCTL_UPDATE),
360 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
361 		  sizeof(short_desc_str), short_desc, NULL, NULL,
362 		  sizeof(kernel_ulong_t),
363 		  (kernel_ulong_t) sizeof(short_desc_str) - 1, NULL,
364 			  ksize_fmt,
365 		  0UL);
366 
367 	buf_in_arg = false;
368 
369 
370 	/* KEYCTL_REVOKE */
371 	do_keyctl(ARG_STR(KEYCTL_REVOKE),
372 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
373 	do_keyctl(ARG_STR(KEYCTL_REVOKE),
374 		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
375 	do_keyctl(ARG_STR(KEYCTL_REVOKE),
376 		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
377 	do_keyctl(ARG_STR(KEYCTL_REVOKE),
378 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
379 		  0UL);
380 
381 
382 	/* KEYCTL_CHOWN */
383 	do_keyctl(ARG_STR(KEYCTL_CHOWN),
384 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
385 		  sizeof(uid_t), ARG_STR(-1), NULL,
386 		  sizeof(gid_t), ARG_STR(-1), NULL, 0UL);
387 	do_keyctl(ARG_STR(KEYCTL_CHOWN),
388 		  sizeof(int32_t), bogus_key1, NULL, "%d",
389 		  sizeof(uid_t), 2718281828U, NULL, "%u",
390 		  sizeof(gid_t), 3141592653U, NULL, "%u", 0UL);
391 
392 
393 	/* KEYCTL_SETPERM */
394 	do_keyctl(ARG_STR(KEYCTL_SETPERM),
395 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQKEY_AUTH_KEY), NULL,
396 		  sizeof(uint32_t), 0xffffffffU,
397 		  "KEY_POS_VIEW|KEY_POS_READ|KEY_POS_WRITE|"
398 		  "KEY_POS_SEARCH|KEY_POS_LINK|KEY_POS_SETATTR|"
399 		  "KEY_USR_VIEW|KEY_USR_READ|KEY_USR_WRITE|"
400 		  "KEY_USR_SEARCH|KEY_USR_LINK|KEY_USR_SETATTR|"
401 		  "KEY_GRP_VIEW|KEY_GRP_READ|KEY_GRP_WRITE|"
402 		  "KEY_GRP_SEARCH|KEY_GRP_LINK|KEY_GRP_SETATTR|"
403 		  "KEY_OTH_VIEW|KEY_OTH_READ|KEY_OTH_WRITE|"
404 		  "KEY_OTH_SEARCH|KEY_OTH_LINK|KEY_OTH_SETATTR|"
405 		  "0xc0c0c0c0", NULL, 0UL);
406 	do_keyctl(ARG_STR(KEYCTL_SETPERM),
407 		  sizeof(int32_t), bogus_key1, NULL, "%d",
408 		  sizeof(uint32_t), 0, NULL, "%#x", 0UL);
409 	do_keyctl(ARG_STR(KEYCTL_SETPERM),
410 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
411 		  sizeof(uint32_t), 0xc0c0c0c0, "0xc0c0c0c0 /* KEY_??? */",
412 			  NULL,
413 		  0UL);
414 
415 
416 	/* KEYCTL_DESCRIBE */
417 	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
418 		  sizeof(int32_t), bogus_key1, NULL, "%d",
419 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
420 		  sizeof(kernel_ulong_t),
421 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
422 		  0UL);
423 	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
424 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
425 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
426 		  sizeof(kernel_ulong_t),
427 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
428 		  0UL);
429 	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
430 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
431 		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
432 		  sizeof(kernel_ulong_t),
433 		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
434 	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
435 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
436 		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
437 		  sizeof(kernel_ulong_t),
438 		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
439 	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
440 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
441 		  (size_t) -4, (uintptr_t) bogus_buf2, NULL, NULL,
442 		  sizeof(kernel_ulong_t),
443 		  (kernel_ulong_t) -4, NULL, ksize_fmt, 0UL);
444 
445 
446 	/* KEYCTL_CLEAR */
447 	do_keyctl(ARG_STR(KEYCTL_CLEAR),
448 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
449 	do_keyctl(ARG_STR(KEYCTL_CLEAR),
450 		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
451 	do_keyctl(ARG_STR(KEYCTL_CLEAR),
452 		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
453 	do_keyctl(ARG_STR(KEYCTL_CLEAR),
454 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
455 		  0UL);
456 
457 
458 	/* KEYCTL_LINK */
459 	do_keyctl(ARG_STR(KEYCTL_LINK),
460 		  sizeof(int32_t), bogus_key1, NULL, "%d",
461 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
462 	do_keyctl(ARG_STR(KEYCTL_LINK),
463 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
464 		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
465 	do_keyctl(ARG_STR(KEYCTL_LINK),
466 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
467 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
468 		  0UL);
469 
470 
471 	/* KEYCTL_UNLINK */
472 	do_keyctl(ARG_STR(KEYCTL_UNLINK),
473 		  sizeof(int32_t), bogus_key1, NULL, "%d",
474 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL,
475 		  0UL);
476 	do_keyctl(ARG_STR(KEYCTL_UNLINK),
477 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
478 		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
479 	do_keyctl(ARG_STR(KEYCTL_UNLINK),
480 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
481 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
482 		  0UL);
483 
484 
485 	/* KEYCTL_SEARCH */
486 	buf_in_arg = true;
487 
488 	do_keyctl(ARG_STR(KEYCTL_SEARCH),
489 		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
490 		  sizeof(char *), ARG_STR(NULL), NULL,
491 		  sizeof(char *), ARG_STR(NULL), NULL,
492 		  sizeof(int32_t), 0, NULL, "%d");
493 	do_keyctl(ARG_STR(KEYCTL_SEARCH),
494 		  sizeof(int32_t), bogus_key1, NULL, "%d",
495 		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
496 		  sizeof(char *), (char *) 0xfffff00dfffff157ULL, NULL, ptr_fmt,
497 		  sizeof(int32_t), ARG_STR(KEY_SPEC_USER_SESSION_KEYRING),
498 			  NULL);
499 	do_keyctl(ARG_STR(KEYCTL_SEARCH),
500 		  sizeof(int32_t), bogus_key2, NULL, "%d",
501 		  sizeof(char *), bogus_str, NULL, ptr_fmt,
502 		  sizeof(char *), bogus_desc, NULL, ptr_fmt,
503 		  sizeof(int32_t), bogus_key1, NULL, "%d");
504 	do_keyctl(ARG_STR(KEYCTL_SEARCH),
505 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
506 		  sizeof(short_type_str), short_type, NULL, NULL,
507 		  sizeof(short_desc_str), short_desc, NULL, NULL,
508 		  sizeof(int32_t), bogus_key2, NULL, "%d");
509 	do_keyctl(ARG_STR(KEYCTL_SEARCH),
510 		  sizeof(int32_t), 0, NULL, "%d",
511 		  sizeof(long_type_str), long_type, NULL, NULL,
512 		  sizeof(long_type_str), long_desc, NULL, NULL,
513 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
514 
515 	buf_in_arg = false;
516 
517 
518 	/* KEYCTL_READ */
519 	nul_terminated_buf = false;
520 
521 	/* Empty result is expected for these */
522 	bogus_buf1[0] = '\377';
523 	bogus_buf2[0] = '\377';
524 
525 	do_keyctl(ARG_STR(KEYCTL_READ),
526 		  sizeof(int32_t), bogus_key1, NULL, "%d",
527 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
528 		  sizeof(kernel_ulong_t),
529 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
530 		  0UL);
531 	do_keyctl(ARG_STR(KEYCTL_READ),
532 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
533 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
534 		  sizeof(kernel_ulong_t),
535 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
536 		  0UL);
537 	do_keyctl(ARG_STR(KEYCTL_READ),
538 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
539 		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
540 		  sizeof(kernel_ulong_t),
541 		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
542 	do_keyctl(ARG_STR(KEYCTL_READ),
543 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
544 		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
545 		  sizeof(kernel_ulong_t),
546 		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
547 	do_keyctl(ARG_STR(KEYCTL_READ),
548 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
549 		  (size_t) -4, (uintptr_t) bogus_buf2, NULL, NULL,
550 		  sizeof(kernel_ulong_t),
551 		  (kernel_ulong_t) -4, NULL, ksize_fmt, 0UL);
552 
553 	nul_terminated_buf = true;
554 
555 	/* KEYCTL_INSTANTIATE */
556 	buf_in_arg = true;
557 
558 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
559 		  sizeof(int32_t), 0, NULL, "%d",
560 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
561 		  sizeof(kernel_ulong_t),
562 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
563 		  sizeof(int32_t), 0, NULL, "%d");
564 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
565 		  sizeof(int32_t), bogus_key1, NULL, "%d",
566 		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
567 		  sizeof(kernel_ulong_t),
568 		  (kernel_ulong_t) 0xdeadfeedLLU, NULL, ksize_fmt,
569 		  sizeof(int32_t), bogus_key1, NULL, "%d");
570 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
571 		  sizeof(int32_t), bogus_key2, NULL, "%d",
572 		  sizeof(char *), bogus_str, NULL, ptr_fmt,
573 		  sizeof(kernel_ulong_t),
574 		  (kernel_ulong_t) 32LLU, NULL, ksize_fmt,
575 		  sizeof(int32_t), bogus_key2, NULL, "%d");
576 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
577 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
578 		  sizeof(short_type_str), short_desc, NULL, NULL,
579 		  sizeof(kernel_ulong_t),
580 		  (kernel_ulong_t) sizeof(short_type_str) - 1, NULL,
581 			  ksize_fmt,
582 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
583 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
584 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL,
585 		  sizeof(long_type_str), long_desc, NULL, NULL,
586 		  sizeof(kernel_ulong_t),
587 		  (kernel_ulong_t) sizeof(long_type_str), NULL, ksize_fmt,
588 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL);
589 
590 	buf_in_arg = false;
591 
592 
593 	/* KEYCTL_NEGATE */
594 	do_keyctl(ARG_STR(KEYCTL_NEGATE),
595 		  sizeof(int32_t), 0, NULL, "%d",
596 		  sizeof(uint32_t), 0, NULL, "%u",
597 		  sizeof(int32_t), 0, NULL, "%d", 0UL);
598 	do_keyctl(ARG_STR(KEYCTL_NEGATE),
599 		  sizeof(int32_t), bogus_key1, NULL, "%d",
600 		  sizeof(uint32_t), 3141592653U, NULL, "%u",
601 		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
602 	do_keyctl(ARG_STR(KEYCTL_NEGATE),
603 		  sizeof(int32_t), bogus_key2, NULL, "%d",
604 		  sizeof(kernel_ulong_t),
605 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
606 		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
607 	do_keyctl(ARG_STR(KEYCTL_NEGATE),
608 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
609 		  sizeof(kernel_ulong_t),
610 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
611 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
612 		  0UL);
613 
614 
615 	/* KEYCTL_SET_REQKEY_KEYRING */
616 	do_keyctl(ARG_STR(KEYCTL_SET_REQKEY_KEYRING),
617 		  sizeof(int32_t), ARG_STR(KEY_REQKEY_DEFL_NO_CHANGE), NULL,
618 		  0UL);
619 	/*
620 	 * Keep it commented out until proper way of faking syscalls is not
621 	 * implemented.
622 	 */
623 	/* do_keyctl(ARG_STR(KEYCTL_SET_REQKEY_KEYRING),
624 		  sizeof(int32_t),
625 		  ARG_STR(KEY_REQKEY_DEFL_REQUESTOR_KEYRING), NULL, 0UL); */
626 	do_keyctl(ARG_STR(KEYCTL_SET_REQKEY_KEYRING),
627 		  sizeof(kernel_ulong_t),
628 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU,
629 		  "0xbadc0ded /* KEY_REQKEY_DEFL_??? */", NULL, 0UL);
630 
631 
632 	/* KEYCTL_SET_TIMEOUT */
633 	do_keyctl(ARG_STR(KEYCTL_SET_TIMEOUT),
634 		  sizeof(int32_t), 0, NULL, "%d",
635 		  sizeof(uint32_t), 0, NULL, "%u", 0UL);
636 	do_keyctl(ARG_STR(KEYCTL_SET_TIMEOUT),
637 		  sizeof(int32_t), bogus_key1, NULL, "%d",
638 		  sizeof(uint32_t), 3141592653U, NULL, "%u", 0UL);
639 	do_keyctl(ARG_STR(KEYCTL_SET_TIMEOUT),
640 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
641 		  sizeof(kernel_ulong_t),
642 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
643 		  0UL);
644 
645 
646 	/* KEYCTL_ASSUME_AUTHORITY */
647 	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
648 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
649 	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
650 		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
651 	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
652 		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
653 	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
654 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
655 		  0UL);
656 
657 
658 	/* KEYCTL_GET_SECURITY */
659 	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
660 		  sizeof(int32_t), bogus_key1, NULL, "%d",
661 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
662 		  sizeof(uint32_t), 0xbadc0dedU, NULL, "%u", 0UL);
663 	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
664 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
665 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
666 		  sizeof(kernel_ulong_t),
667 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
668 		  0UL);
669 	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
670 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
671 		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
672 		  sizeof(kernel_ulong_t),
673 		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
674 	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
675 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
676 		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
677 		  sizeof(kernel_ulong_t),
678 		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
679 	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
680 		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
681 		  (size_t) -4, (uintptr_t) bogus_buf2, NULL, NULL,
682 		  sizeof(kernel_ulong_t),
683 		  (kernel_ulong_t) -4, NULL, ksize_fmt, 0UL);
684 
685 
686 	/* KEYCTL_SESSION_TO_PARENT */
687 	do_keyctl(ARG_STR(KEYCTL_SESSION_TO_PARENT), 0UL);
688 
689 
690 	/* KEYCTL_REJECT */
691 	do_keyctl(ARG_STR(KEYCTL_REJECT),
692 		  sizeof(int32_t), 0, NULL, "%d",
693 		  sizeof(uint32_t), 0, NULL, "%u",
694 		  sizeof(uint32_t), 0, NULL, "%u",
695 		  sizeof(int32_t), 0, NULL, "%d");
696 	do_keyctl(ARG_STR(KEYCTL_REJECT),
697 		  sizeof(int32_t), bogus_key1, NULL, "%d",
698 		  sizeof(uint32_t), 3141592653U, NULL, "%u",
699 		  sizeof(uint32_t), 2718281828U, NULL, "%u",
700 		  sizeof(int32_t), bogus_key1, NULL, "%d");
701 	do_keyctl(ARG_STR(KEYCTL_REJECT),
702 		  sizeof(int32_t), bogus_key2, NULL, "%d",
703 		  sizeof(kernel_ulong_t),
704 		  (kernel_ulong_t) 0xdeadca75facef157LLU, "4207866199", NULL,
705 		  sizeof(kernel_ulong_t),
706 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
707 		  sizeof(int32_t), bogus_key2, NULL, "%d");
708 	do_keyctl(ARG_STR(KEYCTL_REJECT),
709 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
710 		  sizeof(kernel_ulong_t),
711 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
712 		  sizeof(uint32_t), ARG_STR(ENODEV), NULL,
713 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
714 
715 
716 	/* KEYCTL_INSTANTIATE_IOV */
717 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
718 		  sizeof(int32_t), 0, NULL, "%d",
719 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
720 		  sizeof(kernel_ulong_t),
721 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
722 		  sizeof(int32_t), 0, NULL, "%d");
723 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
724 		  sizeof(int32_t), bogus_key1, NULL, "%d",
725 		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
726 		  sizeof(kernel_ulong_t),
727 		  (kernel_ulong_t) 0xdeadfeedLLU, NULL, ksize_fmt,
728 		  sizeof(int32_t), bogus_key1, NULL, "%d");
729 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
730 		  sizeof(int32_t), bogus_key2, NULL, "%d",
731 		  sizeof(char *), key_iov + IOV_SIZE, NULL, ptr_fmt,
732 		  sizeof(kernel_ulong_t),
733 		  (kernel_ulong_t) 32LLU, NULL, ksize_fmt,
734 		  sizeof(int32_t), bogus_key2, NULL, "%d");
735 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
736 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
737 		  sizeof(key_iov), key_iov + IOV_SIZE - 4, key_iov_str1, NULL,
738 		  sizeof(kernel_ulong_t), (kernel_ulong_t) 4, NULL,
739 			  ksize_fmt,
740 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
741 	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
742 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL,
743 		  sizeof(key_iov), key_iov, key_iov_str2, NULL,
744 		  sizeof(kernel_ulong_t),
745 		  (kernel_ulong_t) IOV_SIZE, NULL, ksize_fmt,
746 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL);
747 
748 
749 	/* KEYCTL_INVALIDATE */
750 	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
751 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
752 	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
753 		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
754 	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
755 		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
756 	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
757 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
758 		  0UL);
759 
760 
761 	/* KEYCTL_GET_PERSISTENT */
762 	do_keyctl(ARG_STR(KEYCTL_GET_PERSISTENT),
763 		  sizeof(uid_t), ARG_STR(-1), NULL,
764 		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
765 	do_keyctl(ARG_STR(KEYCTL_GET_PERSISTENT),
766 		  sizeof(uid_t), 2718281828U, NULL, "%u",
767 		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
768 	do_keyctl(ARG_STR(KEYCTL_GET_PERSISTENT),
769 		  sizeof(uid_t), 2718281828U, NULL, "%u",
770 		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
771 		  0UL);
772 
773 
774 	/* KEYCTL_DH_COMPUTE */
775 	nul_terminated_buf = false;
776 
777 	/* Empty result is expected for these */
778 	bogus_buf1[0] = '\377';
779 	bogus_buf2[0] = '\377';
780 
781 	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
782 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
783 		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
784 		  sizeof(kernel_ulong_t),
785 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
786 		  0UL);
787 	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
788 		  sizeof(char *), kcdhp + 1, NULL, ptr_fmt,
789 		  sizeof(char *), (char *) 0xfffff157ffffdeadULL, NULL, ptr_fmt,
790 		  sizeof(kernel_ulong_t),
791 		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
792 		  0UL);
793 	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
794 		  sizeof(kcdhp), kcdhp, kcdhp_str, NULL,
795 		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
796 		  sizeof(kernel_ulong_t),
797 		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
798 	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
799 		  sizeof(kcdhp), kcdhp, kcdhp_str, NULL,
800 		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
801 		  sizeof(kernel_ulong_t),
802 		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
803 	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
804 		  sizeof(kcdhp), kcdhp, kcdhp_str, NULL,
805 		  (size_t) -1, (uintptr_t) bogus_buf2, NULL, NULL,
806 		  sizeof(kernel_ulong_t),
807 		  (kernel_ulong_t) -1, NULL, ksize_fmt, 0UL);
808 
809 	nul_terminated_buf = true;
810 
811 	puts("+++ exited with 0 +++");
812 
813 	return 0;
814 }
815 
816 #else
817 
818 SKIP_MAIN_UNDEFINED("__NR_keyctl");
819 
820 #endif
821