blob: 5b9071ea55ecee62220b91658e225f87985c59c9 [file] [log] [blame]
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +00001/*
Elliott Hughes77c3ff82017-09-08 17:11:00 -07002 * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
Elliott Hughesd35df492017-02-15 15:19:05 -08003 * Copyright (c) 2017 Quentin Monnet <quentin.monnet@6wind.com>
Elliott Hughes28e98bc2018-06-14 16:59:04 -07004 * Copyright (c) 2015-2018 The strace developers.
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +00005 * 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 "defs.h"
Elliott Hughes77c3ff82017-09-08 17:11:00 -070031#include "print_fields.h"
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +000032
33#ifdef HAVE_LINUX_BPF_H
34# include <linux/bpf.h>
35#endif
36
Elliott Hughes28e98bc2018-06-14 16:59:04 -070037#include "bpf_attr.h"
38
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +000039#include "xlat/bpf_commands.h"
Elliott Hughes28e98bc2018-06-14 16:59:04 -070040#include "xlat/bpf_file_mode_flags.h"
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +000041#include "xlat/bpf_map_types.h"
Elliott Hughes77c3ff82017-09-08 17:11:00 -070042#include "xlat/bpf_map_flags.h"
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +000043#include "xlat/bpf_prog_types.h"
Elliott Hughes77c3ff82017-09-08 17:11:00 -070044#include "xlat/bpf_prog_flags.h"
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +000045#include "xlat/bpf_map_update_elem_flags.h"
Elliott Hughesd35df492017-02-15 15:19:05 -080046#include "xlat/bpf_attach_type.h"
Elliott Hughes39bac052017-05-25 16:56:11 -070047#include "xlat/bpf_attach_flags.h"
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +000048
Elliott Hughes77c3ff82017-09-08 17:11:00 -070049#define DECL_BPF_CMD_DECODER(bpf_cmd_decoder) \
50int \
51bpf_cmd_decoder(struct tcb *const tcp, \
52 const kernel_ulong_t addr, \
53 const unsigned int size, \
54 void *const data) \
55/* End of DECL_BPF_CMD_DECODER definition. */
56
Elliott Hughes28e98bc2018-06-14 16:59:04 -070057#define BEGIN_BPF_CMD_DECODER(bpf_cmd) \
58 static DECL_BPF_CMD_DECODER(decode_ ## bpf_cmd) \
59 { \
60 struct bpf_cmd ## _struct attr = {}; \
61 const size_t attr_size = bpf_cmd ## _struct_size; \
62 const unsigned int len = MIN(size, attr_size); \
63 memcpy(&attr, data, len); \
64 do { \
65/* End of BEGIN_BPF_CMD_DECODER definition. */
66
67#define END_BPF_CMD_DECODER(rval) \
68 decode_attr_extra_data(tcp, data, size, attr_size); \
69 } while (0); \
70 tprints("}"); \
71 return (rval); \
72 } \
73/* End of END_BPF_CMD_DECODER definition. */
Elliott Hughes77c3ff82017-09-08 17:11:00 -070074
75#define BPF_CMD_ENTRY(bpf_cmd) \
76 [bpf_cmd] = decode_ ## bpf_cmd
77
78typedef DECL_BPF_CMD_DECODER((*bpf_cmd_decoder_t));
79
Elliott Hughes28e98bc2018-06-14 16:59:04 -070080/*
81 * A note about bpf syscall decoder: it doesn't perform any size sanity checks,
82 * so even if it leads to partial copying of one of the fields, the command
83 * handler will still use the (partially-copied-from-userspace, partially
84 * zeroed) field value. That's why we stop decoding and check for known sizes
85 * that correspond to released versions of the structure used by the specific
86 * command - it looks like the most sensible way to parse this insanity.
87 */
88
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +000089static int
Elliott Hughes77c3ff82017-09-08 17:11:00 -070090decode_attr_extra_data(struct tcb *const tcp,
91 const char *data,
92 unsigned int size,
93 const size_t attr_size)
94{
95 if (size <= attr_size)
96 return 0;
97
98 data += attr_size;
99 size -= attr_size;
100
101 unsigned int i;
102 for (i = 0; i < size; ++i) {
103 if (data[i]) {
104 tprints(", ");
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700105 if (abbrev(tcp)) {
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700106 tprints("...");
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700107 } else {
108 tprintf("/* bytes %zu..%zu */ ",
109 attr_size, attr_size + size - 1);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700110 print_quoted_string(data, size,
111 QUOTE_FORCE_HEX);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700112 }
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700113 return RVAL_DECODED;
114 }
115 }
116
117 return 0;
118}
119
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700120BEGIN_BPF_CMD_DECODER(BPF_MAP_CREATE)
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000121{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700122 PRINT_FIELD_XVAL("{", attr, map_type, bpf_map_types,
123 "BPF_MAP_TYPE_???");
124 PRINT_FIELD_U(", ", attr, key_size);
125 PRINT_FIELD_U(", ", attr, value_size);
126 PRINT_FIELD_U(", ", attr, max_entries);
127 PRINT_FIELD_FLAGS(", ", attr, map_flags, bpf_map_flags, "BPF_F_???");
128 PRINT_FIELD_FD(", ", attr, inner_map_fd, tcp);
Elliott Hughesb7556142018-02-20 17:03:16 -0800129 if (attr.map_flags & BPF_F_NUMA_NODE)
130 PRINT_FIELD_U(", ", attr, numa_node);
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000131}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700132END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000133
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700134BEGIN_BPF_CMD_DECODER(BPF_MAP_LOOKUP_ELEM)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700135{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700136 PRINT_FIELD_FD("{", attr, map_fd, tcp);
137 PRINT_FIELD_X(", ", attr, key);
138 PRINT_FIELD_X(", ", attr, value);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700139}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700140END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700141
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700142BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_ELEM)
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000143{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700144 PRINT_FIELD_FD("{", attr, map_fd, tcp);
145 PRINT_FIELD_X(", ", attr, key);
146 PRINT_FIELD_X(", ", attr, value);
147 PRINT_FIELD_XVAL(", ", attr, flags, bpf_map_update_elem_flags,
148 "BPF_???");
Elliott Hughesd35df492017-02-15 15:19:05 -0800149}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700150END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughesd35df492017-02-15 15:19:05 -0800151
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700152BEGIN_BPF_CMD_DECODER(BPF_MAP_DELETE_ELEM)
Elliott Hughesd35df492017-02-15 15:19:05 -0800153{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700154 PRINT_FIELD_FD("{", attr, map_fd, tcp);
155 PRINT_FIELD_X(", ", attr, key);
Elliott Hughesd35df492017-02-15 15:19:05 -0800156}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700157END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughesd35df492017-02-15 15:19:05 -0800158
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700159BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_NEXT_KEY)
Elliott Hughesd35df492017-02-15 15:19:05 -0800160{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700161 PRINT_FIELD_FD("{", attr, map_fd, tcp);
162 PRINT_FIELD_X(", ", attr, key);
163 PRINT_FIELD_X(", ", attr, next_key);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700164}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700165END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700166
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700167BEGIN_BPF_CMD_DECODER(BPF_PROG_LOAD)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700168{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700169 PRINT_FIELD_XVAL("{", attr, prog_type, bpf_prog_types,
170 "BPF_PROG_TYPE_???");
171 PRINT_FIELD_U(", ", attr, insn_cnt);
172 PRINT_FIELD_X(", ", attr, insns);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700173
174 tprintf(", license=");
175 print_big_u64_addr(attr.license);
176 printstr(tcp, attr.license);
177
178 /* log_* fields were added in Linux commit v3.18-rc1~52^2~1^2~4. */
179 if (len <= offsetof(struct BPF_PROG_LOAD_struct, log_level))
180 break;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700181 PRINT_FIELD_U(", ", attr, log_level);
182 PRINT_FIELD_U(", ", attr, log_size);
183 PRINT_FIELD_X(", ", attr, log_buf);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700184
185 /* kern_version field was added in Linux commit v4.1-rc1~84^2~50. */
186 if (len <= offsetof(struct BPF_PROG_LOAD_struct, kern_version))
187 break;
188 tprintf(", kern_version=KERNEL_VERSION(%u, %u, %u)",
189 attr.kern_version >> 16,
190 (attr.kern_version >> 8) & 0xFF,
191 attr.kern_version & 0xFF);
192
193 /* prog_flags field was added in Linux commit v4.12-rc2~34^2~29^2~2. */
194 if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_flags))
195 break;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700196 PRINT_FIELD_FLAGS(", ", attr, prog_flags, bpf_prog_flags, "BPF_F_???");
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700197}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700198END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700199
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700200BEGIN_BPF_CMD_DECODER(BPF_OBJ_PIN)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700201{
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700202 tprintf("{pathname=");
203 print_big_u64_addr(attr.pathname);
204 printpath(tcp, attr.pathname);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700205
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700206 PRINT_FIELD_FD(", ", attr, bpf_fd, tcp);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700207 if (len <= offsetofend(struct BPF_OBJ_PIN_struct, bpf_fd))
208 break;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700209
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700210 /* file_flags field was added in Linux v4.15-rc1~84^2~384^2~4 */
211 PRINT_FIELD_FLAGS(", ", attr, file_flags, bpf_file_mode_flags,
212 "BPF_F_???");
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700213}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700214END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700215
216#define decode_BPF_OBJ_GET decode_BPF_OBJ_PIN
217
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700218BEGIN_BPF_CMD_DECODER(BPF_PROG_ATTACH)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700219{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700220 PRINT_FIELD_FD("{", attr, target_fd, tcp);
221 PRINT_FIELD_FD(", ", attr, attach_bpf_fd, tcp);
222 PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
223 PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
224 "BPF_F_???");
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700225}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700226END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700227
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700228BEGIN_BPF_CMD_DECODER(BPF_PROG_DETACH)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700229{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700230 PRINT_FIELD_FD("{", attr, target_fd, tcp);
231 PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
Elliott Hughesd35df492017-02-15 15:19:05 -0800232}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700233END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughesd35df492017-02-15 15:19:05 -0800234
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700235BEGIN_BPF_CMD_DECODER(BPF_PROG_TEST_RUN)
Elliott Hughesb7556142018-02-20 17:03:16 -0800236{
Elliott Hughesb7556142018-02-20 17:03:16 -0800237 PRINT_FIELD_FD("{test={", attr, prog_fd, tcp);
238 PRINT_FIELD_U(", ", attr, retval);
239 PRINT_FIELD_U(", ", attr, data_size_in);
240 PRINT_FIELD_U(", ", attr, data_size_out);
241 PRINT_FIELD_X(", ", attr, data_in);
242 PRINT_FIELD_X(", ", attr, data_out);
243 PRINT_FIELD_U(", ", attr, repeat);
244 PRINT_FIELD_U(", ", attr, duration);
245 tprints("}");
Elliott Hughesb7556142018-02-20 17:03:16 -0800246}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700247END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughesb7556142018-02-20 17:03:16 -0800248
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700249BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_NEXT_ID)
Elliott Hughesb7556142018-02-20 17:03:16 -0800250{
Elliott Hughesb7556142018-02-20 17:03:16 -0800251 PRINT_FIELD_U("{", attr, start_id);
252 PRINT_FIELD_U(", ", attr, next_id);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700253 if (len <= offsetofend(struct BPF_PROG_GET_NEXT_ID_struct, next_id))
254 break;
Elliott Hughesb7556142018-02-20 17:03:16 -0800255
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700256 /* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
257 PRINT_FIELD_FLAGS(", ", attr, open_flags, bpf_file_mode_flags,
258 "BPF_F_???");
Elliott Hughesb7556142018-02-20 17:03:16 -0800259}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700260END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughesb7556142018-02-20 17:03:16 -0800261
262#define decode_BPF_MAP_GET_NEXT_ID decode_BPF_PROG_GET_NEXT_ID
263
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700264BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_FD_BY_ID)
Elliott Hughesb7556142018-02-20 17:03:16 -0800265{
Elliott Hughesb7556142018-02-20 17:03:16 -0800266 PRINT_FIELD_U("{", attr, prog_id);
267 PRINT_FIELD_U(", ", attr, next_id);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700268 if (len <= offsetofend(struct BPF_PROG_GET_FD_BY_ID_struct, next_id))
269 break;
Elliott Hughesb7556142018-02-20 17:03:16 -0800270
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700271 /* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
272 PRINT_FIELD_FLAGS(", ", attr, open_flags, bpf_file_mode_flags,
273 "BPF_F_???");
Elliott Hughesb7556142018-02-20 17:03:16 -0800274}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700275END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughesb7556142018-02-20 17:03:16 -0800276
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700277BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_FD_BY_ID)
Elliott Hughesb7556142018-02-20 17:03:16 -0800278{
Elliott Hughesb7556142018-02-20 17:03:16 -0800279 PRINT_FIELD_U("{", attr, map_id);
280 PRINT_FIELD_U(", ", attr, next_id);
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700281 if (len <= offsetofend(struct BPF_MAP_GET_FD_BY_ID_struct, next_id))
282 break;
Elliott Hughesb7556142018-02-20 17:03:16 -0800283
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700284 /* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
285 PRINT_FIELD_FLAGS(", ", attr, open_flags, bpf_file_mode_flags,
286 "BPF_F_???");
Elliott Hughesb7556142018-02-20 17:03:16 -0800287}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700288END_BPF_CMD_DECODER(RVAL_DECODED)
Elliott Hughesb7556142018-02-20 17:03:16 -0800289
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700290BEGIN_BPF_CMD_DECODER(BPF_OBJ_GET_INFO_BY_FD)
Elliott Hughesb7556142018-02-20 17:03:16 -0800291{
Elliott Hughesb7556142018-02-20 17:03:16 -0800292 PRINT_FIELD_FD("{info={", attr, bpf_fd, tcp);
293 PRINT_FIELD_U(", ", attr, info_len);
294 PRINT_FIELD_X(", ", attr, info);
295 tprints("}");
Elliott Hughesb7556142018-02-20 17:03:16 -0800296}
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700297END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
Elliott Hughesb7556142018-02-20 17:03:16 -0800298
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000299SYS_FUNC(bpf)
300{
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700301 static const bpf_cmd_decoder_t bpf_cmd_decoders[] = {
302 BPF_CMD_ENTRY(BPF_MAP_CREATE),
303 BPF_CMD_ENTRY(BPF_MAP_LOOKUP_ELEM),
304 BPF_CMD_ENTRY(BPF_MAP_UPDATE_ELEM),
305 BPF_CMD_ENTRY(BPF_MAP_DELETE_ELEM),
306 BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_KEY),
307 BPF_CMD_ENTRY(BPF_PROG_LOAD),
308 BPF_CMD_ENTRY(BPF_OBJ_PIN),
309 BPF_CMD_ENTRY(BPF_OBJ_GET),
310 BPF_CMD_ENTRY(BPF_PROG_ATTACH),
311 BPF_CMD_ENTRY(BPF_PROG_DETACH),
Elliott Hughesb7556142018-02-20 17:03:16 -0800312 BPF_CMD_ENTRY(BPF_PROG_TEST_RUN),
313 BPF_CMD_ENTRY(BPF_PROG_GET_NEXT_ID),
314 BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_ID),
315 BPF_CMD_ENTRY(BPF_PROG_GET_FD_BY_ID),
316 BPF_CMD_ENTRY(BPF_MAP_GET_FD_BY_ID),
317 BPF_CMD_ENTRY(BPF_OBJ_GET_INFO_BY_FD),
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700318 };
319
Elliott Hughesd35df492017-02-15 15:19:05 -0800320 const unsigned int cmd = tcp->u_arg[0];
321 const kernel_ulong_t addr = tcp->u_arg[1];
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000322 const unsigned int size = tcp->u_arg[2];
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700323 int rc;
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000324
325 if (entering(tcp)) {
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700326 static char *buf;
327
Elliott Hughes28e98bc2018-06-14 16:59:04 -0700328 if (!buf)
329 buf = xmalloc(get_pagesize());
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700330
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000331 printxval(bpf_commands, cmd, "BPF_???");
332 tprints(", ");
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000333
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700334 if (size > 0
335 && size <= get_pagesize()
336 && cmd < ARRAY_SIZE(bpf_cmd_decoders)
337 && bpf_cmd_decoders[cmd]) {
338 rc = umoven_or_printaddr(tcp, addr, size, buf)
339 ? RVAL_DECODED
340 : bpf_cmd_decoders[cmd](tcp, addr, size, buf);
341 } else {
342 printaddr(addr);
343 rc = RVAL_DECODED;
344 }
345 } else {
346 rc = bpf_cmd_decoders[cmd](tcp, addr, size, NULL) | RVAL_DECODED;
Dmitry V. Levinddb53dd2015-07-25 23:55:51 +0000347 }
348
349 if (rc & RVAL_DECODED)
350 tprintf(", %u", size);
351
352 return rc;
353}