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