1 /*
2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2016-2022 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-or-later
8 */
9
10 #include "defs.h"
11 #include <endian.h>
12 #include "netlink.h"
13 #include "nlattr.h"
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
16 #include <linux/sock_diag.h>
17 #include "static_assert.h"
18
19 #include "xlat/netlink_sk_meminfo_indices.h"
20
21 static bool
22 fetch_nlattr(struct tcb *const tcp, struct nlattr *const nlattr,
23 const kernel_ulong_t addr, const unsigned int len,
24 const bool in_array)
25 {
26 if (len < sizeof(struct nlattr)) {
27 printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
28 return false;
29 }
30
31 if (tfetch_obj(tcp, addr, nlattr))
32 return true;
33
34 if (in_array) {
35 tprint_more_data_follows();
36 printaddr_comment(addr);
37 } else {
38 printaddr(addr);
39 }
40
41 return false;
42 }
43
44 static void
45 print_nlattr(const struct nlattr *const nla,
46 const struct xlat *const table,
47 const char *const dflt)
48 {
49 static_assert(NLA_TYPE_MASK == ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER),
50 "wrong NLA_TYPE_MASK");
51
52 tprint_struct_begin();
53 PRINT_FIELD_U(*nla, nla_len);
54 tprint_struct_next();
55 tprints_field_name("nla_type");
56 tprint_flags_begin();
57 if (nla->nla_type & NLA_F_NESTED) {
58 print_xlat(NLA_F_NESTED);
59 tprint_flags_or();
60 }
61 if (nla->nla_type & NLA_F_NET_BYTEORDER) {
62 print_xlat(NLA_F_NET_BYTEORDER);
63 tprint_flags_or();
64 }
65 printxval(table, nla->nla_type & NLA_TYPE_MASK, dflt);
66 tprint_flags_end();
67 tprint_struct_end();
68 }
69
70 static void
71 decode_nlattr_with_data(struct tcb *const tcp,
72 const struct nlattr *const nla,
73 const kernel_ulong_t addr,
74 const unsigned int len,
75 const struct xlat *const table,
76 const char *const dflt,
77 const nla_decoder_t *const decoders,
78 const unsigned int size,
79 const void *const opaque_data)
80 {
81 const unsigned int nla_len = MIN(nla->nla_len, len);
82
83 if (nla_len > NLA_HDRLEN)
84 tprint_array_begin();
85
86 print_nlattr(nla, table, dflt);
87
88 if (nla_len > NLA_HDRLEN) {
89 const unsigned int idx =
90 size ? nla->nla_type & NLA_TYPE_MASK : 0;
91
92 tprint_array_next();
93 if (!decoders
94 || (size && idx >= size)
95 || !decoders[idx]
96 || !decoders[idx](
97 tcp, addr + NLA_HDRLEN,
98 nla_len - NLA_HDRLEN,
99 size ? opaque_data
100 : (const void *) (uintptr_t) nla->nla_type)
101 )
102 printstr_ex(tcp, addr + NLA_HDRLEN,
103 nla_len - NLA_HDRLEN, QUOTE_FORCE_HEX);
104 tprint_array_end();
105 }
106 }
107
108 void
109 decode_nlattr(struct tcb *const tcp,
110 kernel_ulong_t addr,
111 unsigned int len,
112 const struct xlat *const table,
113 const char *const dflt,
114 const nla_decoder_t *const decoders,
115 const unsigned int size,
116 const void *const opaque_data)
117 {
118 struct nlattr nla;
119 bool is_array = false;
120
121 if (decoders && !size && opaque_data)
122 error_func_msg("[xlat %p, dflt \"%s\", decoders %p] "
123 "size is zero (going to pass nla_type as "
124 "decoder argument), but opaque data (%p) is not "
125 "- will be ignored",
126 table, dflt, decoders, opaque_data);
127
128 for (unsigned int elt = 0;
129 fetch_nlattr(tcp, &nla, addr, len, is_array);
130 ++elt) {
131 if (abbrev(tcp) && elt == max_strlen) {
132 tprint_more_data_follows();
133 break;
134 }
135
136 const unsigned int nla_len = NLA_ALIGN(nla.nla_len);
137 kernel_ulong_t next_addr = 0;
138 unsigned int next_len = 0;
139
140 if (nla.nla_len >= NLA_HDRLEN) {
141 next_len = (len >= nla_len) ? len - nla_len : 0;
142
143 if (next_len && addr + nla_len > addr)
144 next_addr = addr + nla_len;
145 }
146
147 if (!is_array && next_addr) {
148 tprint_array_begin();
149 is_array = true;
150 }
151
152 decode_nlattr_with_data(tcp, &nla, addr, len, table, dflt,
153 decoders, size, opaque_data);
154
155 if (!next_addr)
156 break;
157
158 tprint_array_next();
159 addr = next_addr;
160 len = next_len;
161 }
162
163 if (is_array) {
164 tprint_array_end();
165 }
166 }
167
168 bool
169 decode_nla_str(struct tcb *const tcp,
170 const kernel_ulong_t addr,
171 const unsigned int len,
172 const void *const opaque_data)
173 {
174 printstr_ex(tcp, addr, len,
175 QUOTE_OMIT_TRAILING_0 | QUOTE_EXPECT_TRAILING_0);
176
177 return true;
178 }
179
180 bool
181 decode_nla_strn(struct tcb *const tcp,
182 const kernel_ulong_t addr,
183 const unsigned int len,
184 const void *const opaque_data)
185 {
186 printstrn(tcp, addr, len);
187
188 return true;
189 }
190
191 bool
192 decode_nla_meminfo(struct tcb *const tcp,
193 const kernel_ulong_t addr,
194 const unsigned int len,
195 const void *const opaque_data)
196 {
197 uint32_t mem;
198 const size_t nmemb = len / sizeof(mem);
199
200 if (!nmemb)
201 return false;
202
203 unsigned int count = 0;
204 print_array_ex(tcp, addr, nmemb, &mem, sizeof(mem),
205 tfetch_mem, print_uint_array_member, &count,
206 PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
207 netlink_sk_meminfo_indices, "SK_MEMINFO_???");
208
209 return true;
210 }
211
212 bool
213 decode_nla_fd(struct tcb *const tcp,
214 const kernel_ulong_t addr,
215 const unsigned int len,
216 const void *const opaque_data)
217 {
218 int fd;
219
220 if (len < sizeof(fd))
221 return false;
222 else if (!umove_or_printaddr(tcp, addr, &fd))
223 printfd(tcp, fd);
224
225 return true;
226 }
227
228 bool
229 decode_nla_uid(struct tcb *const tcp,
230 const kernel_ulong_t addr,
231 const unsigned int len,
232 const void *const opaque_data)
233 {
234 uint32_t uid;
235
236 if (len < sizeof(uid))
237 return false;
238 else if (!umove_or_printaddr(tcp, addr, &uid))
239 printuid(uid);
240
241 return true;
242 }
243
244 bool
245 decode_nla_gid(struct tcb *const tcp,
246 const kernel_ulong_t addr,
247 const unsigned int len,
248 const void *const opaque_data)
249 {
250 return decode_nla_uid(tcp, addr, len, opaque_data);
251 }
252
253 bool
254 decode_nla_clock_t(struct tcb *const tcp,
255 const kernel_ulong_t addr,
256 const unsigned int len,
257 const void *const opaque_data)
258 {
259 uint64_t val;
260
261 if (len > sizeof(val))
262 return false;
263
264 if (!umoven_to_uint64_or_printaddr(tcp, addr, len, &val))
265 print_clock_t(val);
266
267 return true;
268 }
269
270 bool
271 decode_nla_ifindex(struct tcb *const tcp,
272 const kernel_ulong_t addr,
273 const unsigned int len,
274 const void *const opaque_data)
275 {
276 uint32_t ifindex;
277
278 if (len < sizeof(ifindex))
279 return false;
280 else if (!umove_or_printaddr(tcp, addr, &ifindex))
281 print_ifindex(ifindex);
282
283 return true;
284 }
285
286 bool
287 decode_nla_xval(struct tcb *const tcp,
288 const kernel_ulong_t addr,
289 unsigned int len,
290 const void *const opaque_data)
291 {
292 const struct decode_nla_xlat_opts * const opts = opaque_data;
293 uint64_t data;
294
295 if (len > sizeof(data) || len < opts->size)
296 return false;
297
298 if (opts->size)
299 len = MIN(len, opts->size);
300
301 if (!umoven_to_uint64_or_printaddr(tcp, addr, len, &data)) {
302 if (opts->process_fn)
303 data = opts->process_fn(data);
304 if (opts->fn_str)
305 tprints_arg_begin(opts->fn_str);
306 printxval_ex(opts->xlat, data, opts->dflt, opts->style);
307 if (opts->fn_str)
308 tprint_arg_end();
309 }
310
311 return true;
312 }
313
314 static uint64_t
315 process_host_order(uint64_t val)
316 {
317 return ntohs(val);
318 }
319
320 bool
321 decode_nla_ether_proto(struct tcb *const tcp,
322 const kernel_ulong_t addr,
323 const unsigned int len,
324 const void *const opaque_data)
325 {
326 static const struct decode_nla_xlat_opts opts = {
327 .xlat = ethernet_protocols,
328 .dflt = "ETHER_P_???",
329 .size = 2,
330 .process_fn = process_host_order,
331 .fn_str = "htons",
332 };
333
334 return decode_nla_xval(tcp, addr, len, &opts);
335 }
336
337 bool
338 decode_nla_ip_proto(struct tcb *const tcp,
339 const kernel_ulong_t addr,
340 const unsigned int len,
341 const void *const opaque_data)
342 {
343 static const struct decode_nla_xlat_opts opts = {
344 .xlat = inet_protocols,
345 .dflt = "IPPROTO_???",
346 };
347
348 return decode_nla_xval(tcp, addr, len, &opts);
349 }
350
351 bool
352 decode_nla_hwaddr(struct tcb *const tcp,
353 const kernel_ulong_t addr,
354 const unsigned int len,
355 const void *const opaque_data)
356 {
357 if (len > MAX_ADDR_LEN)
358 return false;
359
360 uint8_t buf[len];
361 const uintptr_t arphrd = (uintptr_t) opaque_data;
362
363 if (!umoven_or_printaddr(tcp, addr, len, buf)) {
364 print_hwaddr("", buf, len, arphrd & NLA_HWADDR_FAMILY_OFFSET
365 ? arphrd & ~NLA_HWADDR_FAMILY_OFFSET : -1U);
366 }
367
368 return true;
369 }
370
371 bool
372 decode_nla_in_addr(struct tcb *const tcp,
373 const kernel_ulong_t addr,
374 const unsigned int len,
375 const void *const opaque_data)
376 {
377 struct in_addr in;
378
379 if (len < sizeof(in))
380 return false;
381 else if (!umove_or_printaddr(tcp, addr, &in))
382 print_inet_addr(AF_INET, &in, sizeof(in), NULL);
383
384 return true;
385 }
386
387 bool
388 decode_nla_in6_addr(struct tcb *const tcp,
389 const kernel_ulong_t addr,
390 const unsigned int len,
391 const void *const opaque_data)
392 {
393 struct in6_addr in6;
394
395 if (len < sizeof(in6))
396 return false;
397 else if (!umove_or_printaddr(tcp, addr, &in6))
398 print_inet_addr(AF_INET6, &in6, sizeof(in6), NULL);
399
400 return true;
401 }
402
403 bool
404 decode_nla_flags(struct tcb *const tcp,
405 const kernel_ulong_t addr,
406 unsigned int len,
407 const void *const opaque_data)
408 {
409 const struct decode_nla_xlat_opts * const opts = opaque_data;
410 uint64_t data;
411
412 if (len > sizeof(data) || len < opts->size)
413 return false;
414
415 if (opts->size)
416 len = MIN(len, opts->size);
417
418 if (!umoven_to_uint64_or_printaddr(tcp, addr, len, &data)) {
419 if (opts->process_fn)
420 data = opts->process_fn(data);
421 if (opts->fn_str)
422 tprints_arg_begin(opts->fn_str);
423 tprint_flags_begin();
424 printflags_ex(data, opts->dflt, opts->style, opts->xlat, NULL);
425 tprint_flags_end();
426 if (opts->fn_str)
427 tprint_arg_end();
428 }
429
430 return true;
431 }
432
433 void
434 decode_nla_af_spec(struct tcb *const tcp,
435 const kernel_ulong_t addr,
436 const unsigned int len,
437 uint8_t af,
438 const struct af_spec_decoder_desc *descs,
439 size_t desc_cnt)
440 {
441 const struct af_spec_decoder_desc *const descs_end = descs + desc_cnt;
442 const struct af_spec_decoder_desc *desc = descs;
443
444 for (; desc < descs_end; desc++) {
445 if (desc->af == af)
446 break;
447 }
448
449 if (desc >= descs_end) {
450 printstr_ex(tcp, addr, len, QUOTE_FORCE_HEX);
451
452 } else {
453 decode_nlattr(tcp, addr, len,
454 desc->xlat, desc->dflt, desc->table, desc->size,
455 NULL);
456 }
457 }
458
459
460 bool
461 decode_nla_be16(struct tcb *const tcp,
462 const kernel_ulong_t addr,
463 const unsigned int len,
464 const void *const opaque_data)
465 {
466 uint16_t num;
467
468 if (len < sizeof(num))
469 return false;
470 else if (!umove_or_printaddr(tcp, addr, &num)) {
471 tprints_arg_begin("htons");
472 PRINT_VAL_U(ntohs(num));
473 tprint_arg_end();
474 }
475
476 return true;
477 }
478
479 bool
480 decode_nla_be64(struct tcb *const tcp,
481 const kernel_ulong_t addr,
482 const unsigned int len,
483 const void *const opaque_data)
484 {
485 #if defined HAVE_BE64TOH || defined be64toh
486 uint64_t num;
487
488 if (len < sizeof(num))
489 return false;
490 else if (!umove_or_printaddr(tcp, addr, &num)) {
491 tprints_arg_begin("htobe64");
492 PRINT_VAL_U(be64toh(num));
493 tprint_arg_end();
494 }
495
496 return true;
497 #else
498 return false;
499 #endif
500 }
501
502 #define DECODE_NLA_INTEGER(name, type, fmt) \
503 bool \
504 decode_nla_ ## name(struct tcb *const tcp, \
505 const kernel_ulong_t addr, \
506 const unsigned int len, \
507 const void *const opaque_data) \
508 { \
509 type num; \
510 \
511 if (len < sizeof(num)) \
512 return false; \
513 if (!umove_or_printaddr(tcp, addr, &num)) \
514 tprintf_string(fmt, num); \
515 return true; \
516 }
517
518 DECODE_NLA_INTEGER(x8, uint8_t, "%#" PRIx8)
519 DECODE_NLA_INTEGER(x16, uint16_t, "%#" PRIx16)
520 DECODE_NLA_INTEGER(x32, uint32_t, "%#" PRIx32)
521 DECODE_NLA_INTEGER(x64, uint64_t, "%#" PRIx64)
522 DECODE_NLA_INTEGER(u8, uint8_t, "%" PRIu8)
523 DECODE_NLA_INTEGER(u16, uint16_t, "%" PRIu16)
524 DECODE_NLA_INTEGER(u32, uint32_t, "%" PRIu32)
525 DECODE_NLA_INTEGER(u64, uint64_t, "%" PRIu64)
526 DECODE_NLA_INTEGER(s8, int8_t, "%" PRId8)
527 DECODE_NLA_INTEGER(s16, int16_t, "%" PRId16)
528 DECODE_NLA_INTEGER(s32, int32_t, "%" PRId32)
529 DECODE_NLA_INTEGER(s64, int64_t, "%" PRId64)
530
531 bool
532 decode_nla_xint(struct tcb *const tcp,
533 const kernel_ulong_t addr,
534 const unsigned int len,
535 const void *const opaque_data)
536 {
537 nla_decoder_t f = NULL;
538
539 switch (len) {
540 case sizeof(uint8_t): f = decode_nla_x8; break;
541 case sizeof(uint16_t): f = decode_nla_x16; break;
542 case sizeof(uint32_t): f = decode_nla_x32; break;
543 case sizeof(uint64_t): f = decode_nla_x64; break;
544 }
545
546 if (f)
547 return f(tcp, addr, len, opaque_data);
548
549 return false;
550 }