1 /*
2 * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>.
3 * Copyright (c) 2021-2022 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #include "defs.h"
10
11 #include <linux/ioctl.h>
12 #include <linux/seccomp.h>
13
14 #include "xlat/seccomp_ioctl_addfd_flags.h"
15 #include "xlat/seccomp_ioctl_resp_flags.h"
16
17 #define SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR SECCOMP_IOR(2, __u64)
18
19 static void
20 print_struct_seccomp_data(struct tcb *const tcp,
21 const struct seccomp_data *const data)
22 {
23 tprint_struct_begin();
24 PRINT_FIELD_SYSCALL_NAME(*data, nr, data->arch);
25 tprint_struct_next();
26 PRINT_FIELD_XVAL(*data, arch, audit_arch, "AUDIT_ARCH_???");
27 tprint_struct_next();
28 PRINT_FIELD_ADDR64(*data, instruction_pointer);
29 tprint_struct_next();
30 PRINT_FIELD_ARRAY(*data, args, tcp, print_xint_array_member);
31 tprint_struct_end();
32 }
33
34 static int
35 print_struct_seccomp_notif(struct tcb *const tcp, const kernel_ulong_t addr)
36 {
37 /*
38 * NB: There is a (poorly designed) seccomp(SECCOMP_GET_NOTIF_SIZES)
39 * operation that hints that struct seccomp_notif/seccomp_notif_data
40 * may vary, but that in turn will change the ID of the respective
41 * ioctl, rendering the whole idea of getting the struct size
42 * in advance dubious at best. Let's just put some safeguards
43 * in place for the time being, in case updated headers bring
44 * changes in either ioctl code or struct size.
45 */
46 CHECK_IOCTL_SIZE(SECCOMP_IOCTL_NOTIF_RECV, 80);
47 CHECK_TYPE_SIZE(struct seccomp_notif, 80);
48 struct seccomp_notif notif;
49
50 if (umove_or_printaddr(tcp, addr, ¬if))
51 return RVAL_IOCTL_DECODED;
52
53 if (entering(tcp)) {
54 if (is_filled((const char *) ¬if, 0, sizeof(notif)))
55 return 0;
56 }
57
58 tprint_struct_begin();
59 PRINT_FIELD_X(notif, id);
60 tprint_struct_next();
61 PRINT_FIELD_TGID(notif, pid, tcp);
62 tprint_struct_next();
63 PRINT_FIELD_X(notif, flags);
64 tprint_struct_next();
65 PRINT_FIELD_OBJ_TCB_PTR(notif, data, tcp, print_struct_seccomp_data);
66 tprint_struct_end();
67
68 if (entering(tcp)) {
69 tprint_value_changed();
70 return 0;
71 }
72
73 return RVAL_IOCTL_DECODED;
74 }
75
76 static void
77 print_struct_seccomp_notif_resp(struct tcb *const tcp,
78 const kernel_ulong_t addr)
79 {
80 CHECK_IOCTL_SIZE(SECCOMP_IOCTL_NOTIF_SEND, 24);
81 CHECK_TYPE_SIZE(struct seccomp_notif_resp, 24);
82 struct seccomp_notif_resp resp;
83
84 if (umove_or_printaddr(tcp, addr, &resp))
85 return;
86
87 tprint_struct_begin();
88 PRINT_FIELD_X(resp, id);
89 tprint_struct_next();
90 PRINT_FIELD_D(resp, val);
91 tprint_struct_next();
92 PRINT_FIELD_ERR_D(resp, error);
93 tprint_struct_next();
94 PRINT_FIELD_FLAGS(resp, flags, seccomp_ioctl_resp_flags,
95 "SECCOMP_USER_NOTIF_FLAG_???");
96 tprint_struct_end();
97 }
98
99 static void
100 print_struct_seccomp_notif_addfd(struct tcb *const tcp,
101 const kernel_ulong_t addr)
102 {
103 CHECK_IOCTL_SIZE(SECCOMP_IOCTL_NOTIF_ADDFD, 24);
104 CHECK_TYPE_SIZE(struct seccomp_notif_addfd, 24);
105 struct seccomp_notif_addfd addfd;
106
107 if (umove_or_printaddr(tcp, addr, &addfd))
108 return;
109
110 tprint_struct_begin();
111 PRINT_FIELD_X(addfd, id);
112 tprint_struct_next();
113 PRINT_FIELD_FLAGS(addfd, flags, seccomp_ioctl_addfd_flags,
114 "SECCOMP_ADDFD_FLAG_???");
115 tprint_struct_next();
116 PRINT_FIELD_FD(addfd, srcfd, tcp);
117 tprint_struct_next();
118 PRINT_FIELD_D(addfd, newfd);
119 tprint_struct_next();
120 PRINT_FIELD_FLAGS(addfd, newfd_flags, open_mode_flags, "O_???");
121 tprint_struct_end();
122 }
123
124 int
125 seccomp_ioctl(struct tcb *const tcp, const unsigned int code,
126 const kernel_ulong_t arg)
127 {
128 switch (code) {
129 case SECCOMP_IOCTL_NOTIF_RECV:
130 if (entering(tcp))
131 tprint_arg_next();
132
133 return print_struct_seccomp_notif(tcp, arg);
134
135 case SECCOMP_IOCTL_NOTIF_SEND:
136 tprint_arg_next();
137 print_struct_seccomp_notif_resp(tcp, arg);
138
139 return RVAL_IOCTL_DECODED;
140
141 case SECCOMP_IOCTL_NOTIF_ID_VALID_WRONG_DIR:
142 case SECCOMP_IOCTL_NOTIF_ID_VALID:
143 tprint_arg_next();
144 printnum_int64(tcp, arg, "%#" PRIx64);
145
146 return RVAL_IOCTL_DECODED;
147
148 case SECCOMP_IOCTL_NOTIF_ADDFD:
149 tprint_arg_next();
150 print_struct_seccomp_notif_addfd(tcp, arg);
151
152 return RVAL_IOCTL_DECODED;
153
154 default:
155 return RVAL_DECODED;
156 }
157 }