|
19 | 19 | #define IP6(aaaa, bbbb, cccc, dddd) \ |
20 | 20 | { bpf_htonl(aaaa), bpf_htonl(bbbb), bpf_htonl(cccc), bpf_htonl(dddd) } |
21 | 21 |
|
| 22 | +/* Macros for least-significant byte and word accesses. */ |
| 23 | +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
| 24 | +#define LSE_INDEX(index, size) (index) |
| 25 | +#else |
| 26 | +#define LSE_INDEX(index, size) ((size) - (index) - 1) |
| 27 | +#endif |
| 28 | +#define LSB(value, index) \ |
| 29 | + (((__u8 *)&(value))[LSE_INDEX((index), sizeof(value))]) |
| 30 | +#define LSW(value, index) \ |
| 31 | + (((__u16 *)&(value))[LSE_INDEX((index), sizeof(value) / 2)]) |
| 32 | + |
22 | 33 | #define MAX_SOCKS 32 |
23 | 34 |
|
24 | 35 | struct { |
@@ -369,171 +380,194 @@ int ctx_narrow_access(struct bpf_sk_lookup *ctx) |
369 | 380 | { |
370 | 381 | struct bpf_sock *sk; |
371 | 382 | int err, family; |
372 | | - __u16 *half; |
373 | | - __u8 *byte; |
374 | 383 | bool v4; |
375 | 384 |
|
376 | 385 | v4 = (ctx->family == AF_INET); |
377 | 386 |
|
378 | 387 | /* Narrow loads from family field */ |
379 | | - byte = (__u8 *)&ctx->family; |
380 | | - half = (__u16 *)&ctx->family; |
381 | | - if (byte[0] != (v4 ? AF_INET : AF_INET6) || |
382 | | - byte[1] != 0 || byte[2] != 0 || byte[3] != 0) |
| 388 | + if (LSB(ctx->family, 0) != (v4 ? AF_INET : AF_INET6) || |
| 389 | + LSB(ctx->family, 1) != 0 || LSB(ctx->family, 2) != 0 || |
| 390 | + LSB(ctx->family, 3) != 0) |
383 | 391 | return SK_DROP; |
384 | | - if (half[0] != (v4 ? AF_INET : AF_INET6)) |
| 392 | + if (LSW(ctx->family, 0) != (v4 ? AF_INET : AF_INET6)) |
385 | 393 | return SK_DROP; |
386 | 394 |
|
387 | | - byte = (__u8 *)&ctx->protocol; |
388 | | - if (byte[0] != IPPROTO_TCP || |
389 | | - byte[1] != 0 || byte[2] != 0 || byte[3] != 0) |
| 395 | + /* Narrow loads from protocol field */ |
| 396 | + if (LSB(ctx->protocol, 0) != IPPROTO_TCP || |
| 397 | + LSB(ctx->protocol, 1) != 0 || LSB(ctx->protocol, 2) != 0 || |
| 398 | + LSB(ctx->protocol, 3) != 0) |
390 | 399 | return SK_DROP; |
391 | | - half = (__u16 *)&ctx->protocol; |
392 | | - if (half[0] != IPPROTO_TCP) |
| 400 | + if (LSW(ctx->protocol, 0) != IPPROTO_TCP) |
393 | 401 | return SK_DROP; |
394 | 402 |
|
395 | 403 | /* Narrow loads from remote_port field. Expect non-0 value. */ |
396 | | - byte = (__u8 *)&ctx->remote_port; |
397 | | - if (byte[0] == 0 && byte[1] == 0 && byte[2] == 0 && byte[3] == 0) |
| 404 | + if (LSB(ctx->remote_port, 0) == 0 && LSB(ctx->remote_port, 1) == 0 && |
| 405 | + LSB(ctx->remote_port, 2) == 0 && LSB(ctx->remote_port, 3) == 0) |
398 | 406 | return SK_DROP; |
399 | | - half = (__u16 *)&ctx->remote_port; |
400 | | - if (half[0] == 0) |
| 407 | + if (LSW(ctx->remote_port, 0) == 0) |
401 | 408 | return SK_DROP; |
402 | 409 |
|
403 | 410 | /* Narrow loads from local_port field. Expect DST_PORT. */ |
404 | | - byte = (__u8 *)&ctx->local_port; |
405 | | - if (byte[0] != ((DST_PORT >> 0) & 0xff) || |
406 | | - byte[1] != ((DST_PORT >> 8) & 0xff) || |
407 | | - byte[2] != 0 || byte[3] != 0) |
| 411 | + if (LSB(ctx->local_port, 0) != ((DST_PORT >> 0) & 0xff) || |
| 412 | + LSB(ctx->local_port, 1) != ((DST_PORT >> 8) & 0xff) || |
| 413 | + LSB(ctx->local_port, 2) != 0 || LSB(ctx->local_port, 3) != 0) |
408 | 414 | return SK_DROP; |
409 | | - half = (__u16 *)&ctx->local_port; |
410 | | - if (half[0] != DST_PORT) |
| 415 | + if (LSW(ctx->local_port, 0) != DST_PORT) |
411 | 416 | return SK_DROP; |
412 | 417 |
|
413 | 418 | /* Narrow loads from IPv4 fields */ |
414 | 419 | if (v4) { |
415 | 420 | /* Expect non-0.0.0.0 in remote_ip4 */ |
416 | | - byte = (__u8 *)&ctx->remote_ip4; |
417 | | - if (byte[0] == 0 && byte[1] == 0 && |
418 | | - byte[2] == 0 && byte[3] == 0) |
| 421 | + if (LSB(ctx->remote_ip4, 0) == 0 && |
| 422 | + LSB(ctx->remote_ip4, 1) == 0 && |
| 423 | + LSB(ctx->remote_ip4, 2) == 0 && |
| 424 | + LSB(ctx->remote_ip4, 3) == 0) |
419 | 425 | return SK_DROP; |
420 | | - half = (__u16 *)&ctx->remote_ip4; |
421 | | - if (half[0] == 0 && half[1] == 0) |
| 426 | + if (LSW(ctx->remote_ip4, 0) == 0 && |
| 427 | + LSW(ctx->remote_ip4, 1) == 0) |
422 | 428 | return SK_DROP; |
423 | 429 |
|
424 | 430 | /* Expect DST_IP4 in local_ip4 */ |
425 | | - byte = (__u8 *)&ctx->local_ip4; |
426 | | - if (byte[0] != ((DST_IP4 >> 0) & 0xff) || |
427 | | - byte[1] != ((DST_IP4 >> 8) & 0xff) || |
428 | | - byte[2] != ((DST_IP4 >> 16) & 0xff) || |
429 | | - byte[3] != ((DST_IP4 >> 24) & 0xff)) |
| 431 | + if (LSB(ctx->local_ip4, 0) != ((DST_IP4 >> 0) & 0xff) || |
| 432 | + LSB(ctx->local_ip4, 1) != ((DST_IP4 >> 8) & 0xff) || |
| 433 | + LSB(ctx->local_ip4, 2) != ((DST_IP4 >> 16) & 0xff) || |
| 434 | + LSB(ctx->local_ip4, 3) != ((DST_IP4 >> 24) & 0xff)) |
430 | 435 | return SK_DROP; |
431 | | - half = (__u16 *)&ctx->local_ip4; |
432 | | - if (half[0] != ((DST_IP4 >> 0) & 0xffff) || |
433 | | - half[1] != ((DST_IP4 >> 16) & 0xffff)) |
| 436 | + if (LSW(ctx->local_ip4, 0) != ((DST_IP4 >> 0) & 0xffff) || |
| 437 | + LSW(ctx->local_ip4, 1) != ((DST_IP4 >> 16) & 0xffff)) |
434 | 438 | return SK_DROP; |
435 | 439 | } else { |
436 | 440 | /* Expect 0.0.0.0 IPs when family != AF_INET */ |
437 | | - byte = (__u8 *)&ctx->remote_ip4; |
438 | | - if (byte[0] != 0 || byte[1] != 0 && |
439 | | - byte[2] != 0 || byte[3] != 0) |
| 441 | + if (LSB(ctx->remote_ip4, 0) != 0 || |
| 442 | + LSB(ctx->remote_ip4, 1) != 0 || |
| 443 | + LSB(ctx->remote_ip4, 2) != 0 || |
| 444 | + LSB(ctx->remote_ip4, 3) != 0) |
440 | 445 | return SK_DROP; |
441 | | - half = (__u16 *)&ctx->remote_ip4; |
442 | | - if (half[0] != 0 || half[1] != 0) |
| 446 | + if (LSW(ctx->remote_ip4, 0) != 0 || |
| 447 | + LSW(ctx->remote_ip4, 1) != 0) |
443 | 448 | return SK_DROP; |
444 | 449 |
|
445 | | - byte = (__u8 *)&ctx->local_ip4; |
446 | | - if (byte[0] != 0 || byte[1] != 0 && |
447 | | - byte[2] != 0 || byte[3] != 0) |
| 450 | + if (LSB(ctx->local_ip4, 0) != 0 || |
| 451 | + LSB(ctx->local_ip4, 1) != 0 || |
| 452 | + LSB(ctx->local_ip4, 2) != 0 || LSB(ctx->local_ip4, 3) != 0) |
448 | 453 | return SK_DROP; |
449 | | - half = (__u16 *)&ctx->local_ip4; |
450 | | - if (half[0] != 0 || half[1] != 0) |
| 454 | + if (LSW(ctx->local_ip4, 0) != 0 || LSW(ctx->local_ip4, 1) != 0) |
451 | 455 | return SK_DROP; |
452 | 456 | } |
453 | 457 |
|
454 | 458 | /* Narrow loads from IPv6 fields */ |
455 | 459 | if (!v4) { |
456 | | - /* Expenct non-:: IP in remote_ip6 */ |
457 | | - byte = (__u8 *)&ctx->remote_ip6; |
458 | | - if (byte[0] == 0 && byte[1] == 0 && |
459 | | - byte[2] == 0 && byte[3] == 0 && |
460 | | - byte[4] == 0 && byte[5] == 0 && |
461 | | - byte[6] == 0 && byte[7] == 0 && |
462 | | - byte[8] == 0 && byte[9] == 0 && |
463 | | - byte[10] == 0 && byte[11] == 0 && |
464 | | - byte[12] == 0 && byte[13] == 0 && |
465 | | - byte[14] == 0 && byte[15] == 0) |
| 460 | + /* Expect non-:: IP in remote_ip6 */ |
| 461 | + if (LSB(ctx->remote_ip6[0], 0) == 0 && |
| 462 | + LSB(ctx->remote_ip6[0], 1) == 0 && |
| 463 | + LSB(ctx->remote_ip6[0], 2) == 0 && |
| 464 | + LSB(ctx->remote_ip6[0], 3) == 0 && |
| 465 | + LSB(ctx->remote_ip6[1], 0) == 0 && |
| 466 | + LSB(ctx->remote_ip6[1], 1) == 0 && |
| 467 | + LSB(ctx->remote_ip6[1], 2) == 0 && |
| 468 | + LSB(ctx->remote_ip6[1], 3) == 0 && |
| 469 | + LSB(ctx->remote_ip6[2], 0) == 0 && |
| 470 | + LSB(ctx->remote_ip6[2], 1) == 0 && |
| 471 | + LSB(ctx->remote_ip6[2], 2) == 0 && |
| 472 | + LSB(ctx->remote_ip6[2], 3) == 0 && |
| 473 | + LSB(ctx->remote_ip6[3], 0) == 0 && |
| 474 | + LSB(ctx->remote_ip6[3], 1) == 0 && |
| 475 | + LSB(ctx->remote_ip6[3], 2) == 0 && |
| 476 | + LSB(ctx->remote_ip6[3], 3) == 0) |
466 | 477 | return SK_DROP; |
467 | | - half = (__u16 *)&ctx->remote_ip6; |
468 | | - if (half[0] == 0 && half[1] == 0 && |
469 | | - half[2] == 0 && half[3] == 0 && |
470 | | - half[4] == 0 && half[5] == 0 && |
471 | | - half[6] == 0 && half[7] == 0) |
| 478 | + if (LSW(ctx->remote_ip6[0], 0) == 0 && |
| 479 | + LSW(ctx->remote_ip6[0], 1) == 0 && |
| 480 | + LSW(ctx->remote_ip6[1], 0) == 0 && |
| 481 | + LSW(ctx->remote_ip6[1], 1) == 0 && |
| 482 | + LSW(ctx->remote_ip6[2], 0) == 0 && |
| 483 | + LSW(ctx->remote_ip6[2], 1) == 0 && |
| 484 | + LSW(ctx->remote_ip6[3], 0) == 0 && |
| 485 | + LSW(ctx->remote_ip6[3], 1) == 0) |
472 | 486 | return SK_DROP; |
473 | | - |
474 | 487 | /* Expect DST_IP6 in local_ip6 */ |
475 | | - byte = (__u8 *)&ctx->local_ip6; |
476 | | - if (byte[0] != ((DST_IP6[0] >> 0) & 0xff) || |
477 | | - byte[1] != ((DST_IP6[0] >> 8) & 0xff) || |
478 | | - byte[2] != ((DST_IP6[0] >> 16) & 0xff) || |
479 | | - byte[3] != ((DST_IP6[0] >> 24) & 0xff) || |
480 | | - byte[4] != ((DST_IP6[1] >> 0) & 0xff) || |
481 | | - byte[5] != ((DST_IP6[1] >> 8) & 0xff) || |
482 | | - byte[6] != ((DST_IP6[1] >> 16) & 0xff) || |
483 | | - byte[7] != ((DST_IP6[1] >> 24) & 0xff) || |
484 | | - byte[8] != ((DST_IP6[2] >> 0) & 0xff) || |
485 | | - byte[9] != ((DST_IP6[2] >> 8) & 0xff) || |
486 | | - byte[10] != ((DST_IP6[2] >> 16) & 0xff) || |
487 | | - byte[11] != ((DST_IP6[2] >> 24) & 0xff) || |
488 | | - byte[12] != ((DST_IP6[3] >> 0) & 0xff) || |
489 | | - byte[13] != ((DST_IP6[3] >> 8) & 0xff) || |
490 | | - byte[14] != ((DST_IP6[3] >> 16) & 0xff) || |
491 | | - byte[15] != ((DST_IP6[3] >> 24) & 0xff)) |
| 488 | + if (LSB(ctx->local_ip6[0], 0) != ((DST_IP6[0] >> 0) & 0xff) || |
| 489 | + LSB(ctx->local_ip6[0], 1) != ((DST_IP6[0] >> 8) & 0xff) || |
| 490 | + LSB(ctx->local_ip6[0], 2) != ((DST_IP6[0] >> 16) & 0xff) || |
| 491 | + LSB(ctx->local_ip6[0], 3) != ((DST_IP6[0] >> 24) & 0xff) || |
| 492 | + LSB(ctx->local_ip6[1], 0) != ((DST_IP6[1] >> 0) & 0xff) || |
| 493 | + LSB(ctx->local_ip6[1], 1) != ((DST_IP6[1] >> 8) & 0xff) || |
| 494 | + LSB(ctx->local_ip6[1], 2) != ((DST_IP6[1] >> 16) & 0xff) || |
| 495 | + LSB(ctx->local_ip6[1], 3) != ((DST_IP6[1] >> 24) & 0xff) || |
| 496 | + LSB(ctx->local_ip6[2], 0) != ((DST_IP6[2] >> 0) & 0xff) || |
| 497 | + LSB(ctx->local_ip6[2], 1) != ((DST_IP6[2] >> 8) & 0xff) || |
| 498 | + LSB(ctx->local_ip6[2], 2) != ((DST_IP6[2] >> 16) & 0xff) || |
| 499 | + LSB(ctx->local_ip6[2], 3) != ((DST_IP6[2] >> 24) & 0xff) || |
| 500 | + LSB(ctx->local_ip6[3], 0) != ((DST_IP6[3] >> 0) & 0xff) || |
| 501 | + LSB(ctx->local_ip6[3], 1) != ((DST_IP6[3] >> 8) & 0xff) || |
| 502 | + LSB(ctx->local_ip6[3], 2) != ((DST_IP6[3] >> 16) & 0xff) || |
| 503 | + LSB(ctx->local_ip6[3], 3) != ((DST_IP6[3] >> 24) & 0xff)) |
492 | 504 | return SK_DROP; |
493 | | - half = (__u16 *)&ctx->local_ip6; |
494 | | - if (half[0] != ((DST_IP6[0] >> 0) & 0xffff) || |
495 | | - half[1] != ((DST_IP6[0] >> 16) & 0xffff) || |
496 | | - half[2] != ((DST_IP6[1] >> 0) & 0xffff) || |
497 | | - half[3] != ((DST_IP6[1] >> 16) & 0xffff) || |
498 | | - half[4] != ((DST_IP6[2] >> 0) & 0xffff) || |
499 | | - half[5] != ((DST_IP6[2] >> 16) & 0xffff) || |
500 | | - half[6] != ((DST_IP6[3] >> 0) & 0xffff) || |
501 | | - half[7] != ((DST_IP6[3] >> 16) & 0xffff)) |
| 505 | + if (LSW(ctx->local_ip6[0], 0) != ((DST_IP6[0] >> 0) & 0xffff) || |
| 506 | + LSW(ctx->local_ip6[0], 1) != |
| 507 | + ((DST_IP6[0] >> 16) & 0xffff) || |
| 508 | + LSW(ctx->local_ip6[1], 0) != ((DST_IP6[1] >> 0) & 0xffff) || |
| 509 | + LSW(ctx->local_ip6[1], 1) != |
| 510 | + ((DST_IP6[1] >> 16) & 0xffff) || |
| 511 | + LSW(ctx->local_ip6[2], 0) != ((DST_IP6[2] >> 0) & 0xffff) || |
| 512 | + LSW(ctx->local_ip6[2], 1) != |
| 513 | + ((DST_IP6[2] >> 16) & 0xffff) || |
| 514 | + LSW(ctx->local_ip6[3], 0) != ((DST_IP6[3] >> 0) & 0xffff) || |
| 515 | + LSW(ctx->local_ip6[3], 1) != ((DST_IP6[3] >> 16) & 0xffff)) |
502 | 516 | return SK_DROP; |
503 | 517 | } else { |
504 | 518 | /* Expect :: IPs when family != AF_INET6 */ |
505 | | - byte = (__u8 *)&ctx->remote_ip6; |
506 | | - if (byte[0] != 0 || byte[1] != 0 || |
507 | | - byte[2] != 0 || byte[3] != 0 || |
508 | | - byte[4] != 0 || byte[5] != 0 || |
509 | | - byte[6] != 0 || byte[7] != 0 || |
510 | | - byte[8] != 0 || byte[9] != 0 || |
511 | | - byte[10] != 0 || byte[11] != 0 || |
512 | | - byte[12] != 0 || byte[13] != 0 || |
513 | | - byte[14] != 0 || byte[15] != 0) |
| 519 | + if (LSB(ctx->remote_ip6[0], 0) != 0 || |
| 520 | + LSB(ctx->remote_ip6[0], 1) != 0 || |
| 521 | + LSB(ctx->remote_ip6[0], 2) != 0 || |
| 522 | + LSB(ctx->remote_ip6[0], 3) != 0 || |
| 523 | + LSB(ctx->remote_ip6[1], 0) != 0 || |
| 524 | + LSB(ctx->remote_ip6[1], 1) != 0 || |
| 525 | + LSB(ctx->remote_ip6[1], 2) != 0 || |
| 526 | + LSB(ctx->remote_ip6[1], 3) != 0 || |
| 527 | + LSB(ctx->remote_ip6[2], 0) != 0 || |
| 528 | + LSB(ctx->remote_ip6[2], 1) != 0 || |
| 529 | + LSB(ctx->remote_ip6[2], 2) != 0 || |
| 530 | + LSB(ctx->remote_ip6[2], 3) != 0 || |
| 531 | + LSB(ctx->remote_ip6[3], 0) != 0 || |
| 532 | + LSB(ctx->remote_ip6[3], 1) != 0 || |
| 533 | + LSB(ctx->remote_ip6[3], 2) != 0 || |
| 534 | + LSB(ctx->remote_ip6[3], 3) != 0) |
514 | 535 | return SK_DROP; |
515 | | - half = (__u16 *)&ctx->remote_ip6; |
516 | | - if (half[0] != 0 || half[1] != 0 || |
517 | | - half[2] != 0 || half[3] != 0 || |
518 | | - half[4] != 0 || half[5] != 0 || |
519 | | - half[6] != 0 || half[7] != 0) |
| 536 | + if (LSW(ctx->remote_ip6[0], 0) != 0 || |
| 537 | + LSW(ctx->remote_ip6[0], 1) != 0 || |
| 538 | + LSW(ctx->remote_ip6[1], 0) != 0 || |
| 539 | + LSW(ctx->remote_ip6[1], 1) != 0 || |
| 540 | + LSW(ctx->remote_ip6[2], 0) != 0 || |
| 541 | + LSW(ctx->remote_ip6[2], 1) != 0 || |
| 542 | + LSW(ctx->remote_ip6[3], 0) != 0 || |
| 543 | + LSW(ctx->remote_ip6[3], 1) != 0) |
520 | 544 | return SK_DROP; |
521 | 545 |
|
522 | | - byte = (__u8 *)&ctx->local_ip6; |
523 | | - if (byte[0] != 0 || byte[1] != 0 || |
524 | | - byte[2] != 0 || byte[3] != 0 || |
525 | | - byte[4] != 0 || byte[5] != 0 || |
526 | | - byte[6] != 0 || byte[7] != 0 || |
527 | | - byte[8] != 0 || byte[9] != 0 || |
528 | | - byte[10] != 0 || byte[11] != 0 || |
529 | | - byte[12] != 0 || byte[13] != 0 || |
530 | | - byte[14] != 0 || byte[15] != 0) |
| 546 | + if (LSB(ctx->local_ip6[0], 0) != 0 || |
| 547 | + LSB(ctx->local_ip6[0], 1) != 0 || |
| 548 | + LSB(ctx->local_ip6[0], 2) != 0 || |
| 549 | + LSB(ctx->local_ip6[0], 3) != 0 || |
| 550 | + LSB(ctx->local_ip6[1], 0) != 0 || |
| 551 | + LSB(ctx->local_ip6[1], 1) != 0 || |
| 552 | + LSB(ctx->local_ip6[1], 2) != 0 || |
| 553 | + LSB(ctx->local_ip6[1], 3) != 0 || |
| 554 | + LSB(ctx->local_ip6[2], 0) != 0 || |
| 555 | + LSB(ctx->local_ip6[2], 1) != 0 || |
| 556 | + LSB(ctx->local_ip6[2], 2) != 0 || |
| 557 | + LSB(ctx->local_ip6[2], 3) != 0 || |
| 558 | + LSB(ctx->local_ip6[3], 0) != 0 || |
| 559 | + LSB(ctx->local_ip6[3], 1) != 0 || |
| 560 | + LSB(ctx->local_ip6[3], 2) != 0 || |
| 561 | + LSB(ctx->local_ip6[3], 3) != 0) |
531 | 562 | return SK_DROP; |
532 | | - half = (__u16 *)&ctx->local_ip6; |
533 | | - if (half[0] != 0 || half[1] != 0 || |
534 | | - half[2] != 0 || half[3] != 0 || |
535 | | - half[4] != 0 || half[5] != 0 || |
536 | | - half[6] != 0 || half[7] != 0) |
| 563 | + if (LSW(ctx->remote_ip6[0], 0) != 0 || |
| 564 | + LSW(ctx->remote_ip6[0], 1) != 0 || |
| 565 | + LSW(ctx->remote_ip6[1], 0) != 0 || |
| 566 | + LSW(ctx->remote_ip6[1], 1) != 0 || |
| 567 | + LSW(ctx->remote_ip6[2], 0) != 0 || |
| 568 | + LSW(ctx->remote_ip6[2], 1) != 0 || |
| 569 | + LSW(ctx->remote_ip6[3], 0) != 0 || |
| 570 | + LSW(ctx->remote_ip6[3], 1) != 0) |
537 | 571 | return SK_DROP; |
538 | 572 | } |
539 | 573 |
|
|
0 commit comments