1 /*
2 * Check decoding of seccomp SECCOMP_GET_NOTIF_SIZES.
3 *
4 * Copyright (c) 2017-2021 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13
14 #include <errno.h>
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <unistd.h>
18
19 #include <linux/seccomp.h>
20
21 #ifndef SECCOMP_GET_NOTIF_SIZES
22 # define SECCOMP_GET_NOTIF_SIZES 3
23 #endif
24
25 #ifndef INJECT_RETVAL
26 # define INJECT_RETVAL 0
27 #endif
28
29 #if INJECT_RETVAL
30 # define INJ_STR " (INJECTED)"
31 #else
32 # define INJ_STR ""
33 #endif
34
35 static const char *errstr;
36
37 static long
38 k_seccomp(const kernel_ulong_t op, const kernel_ulong_t flags,
39 const kernel_ulong_t args)
40 {
41 const long rc = syscall(__NR_seccomp, op, flags, args);
42 errstr = sprintrc(rc);
43 return rc;
44 }
45
46 int
47 main(void)
48 {
49 uint16_t *sizes = tail_alloc(sizeof(*sizes) * 3);
50 kernel_ulong_t op = (kernel_ulong_t) 0xfacefeed00000000ULL
51 | SECCOMP_GET_NOTIF_SIZES;
52 kernel_ulong_t flags = (kernel_ulong_t) 0xdeadbeef00000000ULL;
53 long rc;
54
55 rc = k_seccomp(op, flags | 0xdeadbeef, 0);
56 printf("seccomp(SECCOMP_GET_NOTIF_SIZES, 0xdeadbeef, NULL) = %s"
57 INJ_STR "\n", errstr);
58
59 if (F8ILL_KULONG_SUPPORTED) {
60 rc = k_seccomp(op, flags, f8ill_ptr_to_kulong(0));
61 printf("seccomp(SECCOMP_GET_NOTIF_SIZES, 0, %#llx) = %s"
62 INJ_STR "\n",
63 (unsigned long long) f8ill_ptr_to_kulong(0), errstr);
64 }
65
66 rc = k_seccomp(op, flags, (uintptr_t) (sizes + 1));
67 printf("seccomp(SECCOMP_GET_NOTIF_SIZES, 0, %p) = %s" INJ_STR "\n",
68 sizes + 1, errstr);
69
70 for (size_t i = 0; i < 2; i++) {
71 sizes[0] = 0xcafe;
72 sizes[1] = 0xfeed;
73 sizes[2] = 0xbeef;
74 rc = k_seccomp(op, flags | (i * 0xdeadc0de), (uintptr_t) sizes);
75 if (rc < 0
76 && errno != ENOSYS && errno != EINVAL && errno != EPERM) {
77 perror_msg_and_fail("Unexpected seccomp("
78 "SECCOMP_GET_NOTIF_SIZES) error");
79 }
80 printf("seccomp(SECCOMP_GET_NOTIF_SIZES, %s, ",
81 i ? "0xdeadc0de" : "0");
82 if (rc >= 0) {
83 printf("{seccomp_notif=%hu, seccomp_notif_resp=%hu"
84 ", seccomp_data=%hu}",
85 (uint16_t) (INJECT_RETVAL ? 0xcafe : sizes[0]),
86 (uint16_t) (INJECT_RETVAL ? 0xfeed : sizes[1]),
87 (uint16_t) (INJECT_RETVAL ? 0xbeef : sizes[2]));
88 } else {
89 printf("%p", sizes);
90 }
91
92 printf(") = %s" INJ_STR "\n", errstr);
93 }
94
95 puts("+++ exited with 0 +++");
96 return 0;
97 }