hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/tools/testing/selftests/bpf/test_sock_addr.c
....@@ -76,6 +76,7 @@
7676 enum {
7777 LOAD_REJECT,
7878 ATTACH_REJECT,
79
+ ATTACH_OKAY,
7980 SYSCALL_EPERM,
8081 SYSCALL_ENOTSUPP,
8182 SUCCESS,
....@@ -88,9 +89,13 @@
8889 static int connect6_prog_load(const struct sock_addr_test *test);
8990 static int sendmsg_allow_prog_load(const struct sock_addr_test *test);
9091 static int sendmsg_deny_prog_load(const struct sock_addr_test *test);
92
+static int recvmsg_allow_prog_load(const struct sock_addr_test *test);
93
+static int recvmsg_deny_prog_load(const struct sock_addr_test *test);
9194 static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test);
95
+static int recvmsg4_rw_asm_prog_load(const struct sock_addr_test *test);
9296 static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test);
9397 static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test);
98
+static int recvmsg6_rw_asm_prog_load(const struct sock_addr_test *test);
9499 static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test);
95100 static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test);
96101 static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test);
....@@ -507,6 +512,92 @@
507512 SRC6_REWRITE_IP,
508513 SYSCALL_EPERM,
509514 },
515
+
516
+ /* recvmsg */
517
+ {
518
+ "recvmsg4: return code ok",
519
+ recvmsg_allow_prog_load,
520
+ BPF_CGROUP_UDP4_RECVMSG,
521
+ BPF_CGROUP_UDP4_RECVMSG,
522
+ AF_INET,
523
+ SOCK_DGRAM,
524
+ NULL,
525
+ 0,
526
+ NULL,
527
+ 0,
528
+ NULL,
529
+ ATTACH_OKAY,
530
+ },
531
+ {
532
+ "recvmsg4: return code !ok",
533
+ recvmsg_deny_prog_load,
534
+ BPF_CGROUP_UDP4_RECVMSG,
535
+ BPF_CGROUP_UDP4_RECVMSG,
536
+ AF_INET,
537
+ SOCK_DGRAM,
538
+ NULL,
539
+ 0,
540
+ NULL,
541
+ 0,
542
+ NULL,
543
+ LOAD_REJECT,
544
+ },
545
+ {
546
+ "recvmsg6: return code ok",
547
+ recvmsg_allow_prog_load,
548
+ BPF_CGROUP_UDP6_RECVMSG,
549
+ BPF_CGROUP_UDP6_RECVMSG,
550
+ AF_INET6,
551
+ SOCK_DGRAM,
552
+ NULL,
553
+ 0,
554
+ NULL,
555
+ 0,
556
+ NULL,
557
+ ATTACH_OKAY,
558
+ },
559
+ {
560
+ "recvmsg6: return code !ok",
561
+ recvmsg_deny_prog_load,
562
+ BPF_CGROUP_UDP6_RECVMSG,
563
+ BPF_CGROUP_UDP6_RECVMSG,
564
+ AF_INET6,
565
+ SOCK_DGRAM,
566
+ NULL,
567
+ 0,
568
+ NULL,
569
+ 0,
570
+ NULL,
571
+ LOAD_REJECT,
572
+ },
573
+ {
574
+ "recvmsg4: rewrite IP & port (asm)",
575
+ recvmsg4_rw_asm_prog_load,
576
+ BPF_CGROUP_UDP4_RECVMSG,
577
+ BPF_CGROUP_UDP4_RECVMSG,
578
+ AF_INET,
579
+ SOCK_DGRAM,
580
+ SERV4_REWRITE_IP,
581
+ SERV4_REWRITE_PORT,
582
+ SERV4_REWRITE_IP,
583
+ SERV4_REWRITE_PORT,
584
+ SERV4_IP,
585
+ SUCCESS,
586
+ },
587
+ {
588
+ "recvmsg6: rewrite IP & port (asm)",
589
+ recvmsg6_rw_asm_prog_load,
590
+ BPF_CGROUP_UDP6_RECVMSG,
591
+ BPF_CGROUP_UDP6_RECVMSG,
592
+ AF_INET6,
593
+ SOCK_DGRAM,
594
+ SERV6_REWRITE_IP,
595
+ SERV6_REWRITE_PORT,
596
+ SERV6_REWRITE_IP,
597
+ SERV6_REWRITE_PORT,
598
+ SERV6_IP,
599
+ SUCCESS,
600
+ },
510601 };
511602
512603 static int mk_sockaddr(int domain, const char *ip, unsigned short port,
....@@ -586,13 +677,15 @@
586677 uint8_t u4_addr8[4];
587678 uint16_t u4_addr16[2];
588679 uint32_t u4_addr32;
589
- } ip4;
680
+ } ip4, port;
590681 struct sockaddr_in addr4_rw;
591682
592683 if (inet_pton(AF_INET, SERV4_IP, (void *)&ip4) != 1) {
593684 log_err("Invalid IPv4: %s", SERV4_IP);
594685 return -1;
595686 }
687
+
688
+ port.u4_addr32 = htons(SERV4_PORT);
596689
597690 if (mk_sockaddr(AF_INET, SERV4_REWRITE_IP, SERV4_REWRITE_PORT,
598691 (struct sockaddr *)&addr4_rw, sizeof(addr4_rw)) == -1)
....@@ -605,29 +698,65 @@
605698 /* if (sk.family == AF_INET && */
606699 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
607700 offsetof(struct bpf_sock_addr, family)),
608
- BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET, 16),
701
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET, 32),
609702
610703 /* (sk.type == SOCK_DGRAM || sk.type == SOCK_STREAM) && */
611704 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
612705 offsetof(struct bpf_sock_addr, type)),
613706 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, SOCK_DGRAM, 1),
614707 BPF_JMP_A(1),
615
- BPF_JMP_IMM(BPF_JNE, BPF_REG_7, SOCK_STREAM, 12),
708
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, SOCK_STREAM, 28),
616709
617710 /* 1st_byte_of_user_ip4 == expected && */
618711 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_6,
619712 offsetof(struct bpf_sock_addr, user_ip4)),
620
- BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr8[0], 10),
713
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr8[0], 26),
714
+
715
+ /* 2nd_byte_of_user_ip4 == expected && */
716
+ BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_6,
717
+ offsetof(struct bpf_sock_addr, user_ip4) + 1),
718
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr8[1], 24),
719
+
720
+ /* 3rd_byte_of_user_ip4 == expected && */
721
+ BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_6,
722
+ offsetof(struct bpf_sock_addr, user_ip4) + 2),
723
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr8[2], 22),
724
+
725
+ /* 4th_byte_of_user_ip4 == expected && */
726
+ BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_6,
727
+ offsetof(struct bpf_sock_addr, user_ip4) + 3),
728
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr8[3], 20),
621729
622730 /* 1st_half_of_user_ip4 == expected && */
623731 BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_6,
624732 offsetof(struct bpf_sock_addr, user_ip4)),
625
- BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr16[0], 8),
733
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr16[0], 18),
626734
627
- /* whole_user_ip4 == expected) { */
735
+ /* 2nd_half_of_user_ip4 == expected && */
736
+ BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_6,
737
+ offsetof(struct bpf_sock_addr, user_ip4) + 2),
738
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr16[1], 16),
739
+
740
+ /* whole_user_ip4 == expected && */
628741 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
629742 offsetof(struct bpf_sock_addr, user_ip4)),
630743 BPF_LD_IMM64(BPF_REG_8, ip4.u4_addr32), /* See [2]. */
744
+ BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_8, 12),
745
+
746
+ /* 1st_byte_of_user_port == expected && */
747
+ BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_6,
748
+ offsetof(struct bpf_sock_addr, user_port)),
749
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, port.u4_addr8[0], 10),
750
+
751
+ /* 1st_half_of_user_port == expected && */
752
+ BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_6,
753
+ offsetof(struct bpf_sock_addr, user_port)),
754
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, port.u4_addr16[0], 8),
755
+
756
+ /* user_port == expected) { */
757
+ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
758
+ offsetof(struct bpf_sock_addr, user_port)),
759
+ BPF_LD_IMM64(BPF_REG_8, port.u4_addr32), /* See [2]. */
631760 BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_8, 4),
632761
633762 /* user_ip4 = addr4_rw.sin_addr */
....@@ -725,6 +854,7 @@
725854 attr.file = path;
726855 attr.prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
727856 attr.expected_attach_type = test->expected_attach_type;
857
+ attr.prog_flags = BPF_F_TEST_RND_HI32;
728858
729859 if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) {
730860 if (test->expected_result != LOAD_REJECT)
....@@ -745,8 +875,8 @@
745875 return load_path(test, CONNECT6_PROG_PATH);
746876 }
747877
748
-static int sendmsg_ret_only_prog_load(const struct sock_addr_test *test,
749
- int32_t rc)
878
+static int xmsg_ret_only_prog_load(const struct sock_addr_test *test,
879
+ int32_t rc)
750880 {
751881 struct bpf_insn insns[] = {
752882 /* return rc */
....@@ -758,12 +888,22 @@
758888
759889 static int sendmsg_allow_prog_load(const struct sock_addr_test *test)
760890 {
761
- return sendmsg_ret_only_prog_load(test, /*rc*/ 1);
891
+ return xmsg_ret_only_prog_load(test, /*rc*/ 1);
762892 }
763893
764894 static int sendmsg_deny_prog_load(const struct sock_addr_test *test)
765895 {
766
- return sendmsg_ret_only_prog_load(test, /*rc*/ 0);
896
+ return xmsg_ret_only_prog_load(test, /*rc*/ 0);
897
+}
898
+
899
+static int recvmsg_allow_prog_load(const struct sock_addr_test *test)
900
+{
901
+ return xmsg_ret_only_prog_load(test, /*rc*/ 1);
902
+}
903
+
904
+static int recvmsg_deny_prog_load(const struct sock_addr_test *test)
905
+{
906
+ return xmsg_ret_only_prog_load(test, /*rc*/ 0);
767907 }
768908
769909 static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test)
....@@ -806,6 +946,47 @@
806946
807947 /* user_port = dst4_rw_addr.sin_port */
808948 BPF_MOV32_IMM(BPF_REG_7, dst4_rw_addr.sin_port),
949
+ BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
950
+ offsetof(struct bpf_sock_addr, user_port)),
951
+ /* } */
952
+
953
+ /* return 1 */
954
+ BPF_MOV64_IMM(BPF_REG_0, 1),
955
+ BPF_EXIT_INSN(),
956
+ };
957
+
958
+ return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
959
+}
960
+
961
+static int recvmsg4_rw_asm_prog_load(const struct sock_addr_test *test)
962
+{
963
+ struct sockaddr_in src4_rw_addr;
964
+
965
+ if (mk_sockaddr(AF_INET, SERV4_IP, SERV4_PORT,
966
+ (struct sockaddr *)&src4_rw_addr,
967
+ sizeof(src4_rw_addr)) == -1)
968
+ return -1;
969
+
970
+ struct bpf_insn insns[] = {
971
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
972
+
973
+ /* if (sk.family == AF_INET && */
974
+ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
975
+ offsetof(struct bpf_sock_addr, family)),
976
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET, 6),
977
+
978
+ /* sk.type == SOCK_DGRAM) { */
979
+ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
980
+ offsetof(struct bpf_sock_addr, type)),
981
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, SOCK_DGRAM, 4),
982
+
983
+ /* user_ip4 = src4_rw_addr.sin_addr */
984
+ BPF_MOV32_IMM(BPF_REG_7, src4_rw_addr.sin_addr.s_addr),
985
+ BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
986
+ offsetof(struct bpf_sock_addr, user_ip4)),
987
+
988
+ /* user_port = src4_rw_addr.sin_port */
989
+ BPF_MOV32_IMM(BPF_REG_7, src4_rw_addr.sin_port),
809990 BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
810991 offsetof(struct bpf_sock_addr, user_port)),
811992 /* } */
....@@ -879,6 +1060,39 @@
8791060 static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test)
8801061 {
8811062 return sendmsg6_rw_dst_asm_prog_load(test, SERV6_REWRITE_IP);
1063
+}
1064
+
1065
+static int recvmsg6_rw_asm_prog_load(const struct sock_addr_test *test)
1066
+{
1067
+ struct sockaddr_in6 src6_rw_addr;
1068
+
1069
+ if (mk_sockaddr(AF_INET6, SERV6_IP, SERV6_PORT,
1070
+ (struct sockaddr *)&src6_rw_addr,
1071
+ sizeof(src6_rw_addr)) == -1)
1072
+ return -1;
1073
+
1074
+ struct bpf_insn insns[] = {
1075
+ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
1076
+
1077
+ /* if (sk.family == AF_INET6) { */
1078
+ BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
1079
+ offsetof(struct bpf_sock_addr, family)),
1080
+ BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET6, 10),
1081
+
1082
+ STORE_IPV6(user_ip6, src6_rw_addr.sin6_addr.s6_addr32),
1083
+
1084
+ /* user_port = dst6_rw_addr.sin6_port */
1085
+ BPF_MOV32_IMM(BPF_REG_7, src6_rw_addr.sin6_port),
1086
+ BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
1087
+ offsetof(struct bpf_sock_addr, user_port)),
1088
+ /* } */
1089
+
1090
+ /* return 1 */
1091
+ BPF_MOV64_IMM(BPF_REG_0, 1),
1092
+ BPF_EXIT_INSN(),
1093
+ };
1094
+
1095
+ return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
8821096 }
8831097
8841098 static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test)
....@@ -1262,13 +1476,13 @@
12621476 return err;
12631477 }
12641478
1265
-static int run_sendmsg_test_case(const struct sock_addr_test *test)
1479
+static int run_xmsg_test_case(const struct sock_addr_test *test, int max_cmsg)
12661480 {
12671481 socklen_t addr_len = sizeof(struct sockaddr_storage);
1268
- struct sockaddr_storage expected_src_addr;
1269
- struct sockaddr_storage requested_addr;
12701482 struct sockaddr_storage expected_addr;
1271
- struct sockaddr_storage real_src_addr;
1483
+ struct sockaddr_storage server_addr;
1484
+ struct sockaddr_storage sendmsg_addr;
1485
+ struct sockaddr_storage recvmsg_addr;
12721486 int clientfd = -1;
12731487 int servfd = -1;
12741488 int set_cmsg;
....@@ -1277,20 +1491,19 @@
12771491 if (test->type != SOCK_DGRAM)
12781492 goto err;
12791493
1280
- if (init_addrs(test, &requested_addr, &expected_addr,
1281
- &expected_src_addr))
1494
+ if (init_addrs(test, &sendmsg_addr, &server_addr, &expected_addr))
12821495 goto err;
12831496
12841497 /* Prepare server to sendmsg to */
1285
- servfd = start_server(test->type, &expected_addr, addr_len);
1498
+ servfd = start_server(test->type, &server_addr, addr_len);
12861499 if (servfd == -1)
12871500 goto err;
12881501
1289
- for (set_cmsg = 0; set_cmsg <= 1; ++set_cmsg) {
1502
+ for (set_cmsg = 0; set_cmsg <= max_cmsg; ++set_cmsg) {
12901503 if (clientfd >= 0)
12911504 close(clientfd);
12921505
1293
- clientfd = sendmsg_to_server(test->type, &requested_addr,
1506
+ clientfd = sendmsg_to_server(test->type, &sendmsg_addr,
12941507 addr_len, set_cmsg, /*flags*/0,
12951508 &err);
12961509 if (err)
....@@ -1310,10 +1523,10 @@
13101523 * specific packet may differ from the one used by default and
13111524 * returned by getsockname(2).
13121525 */
1313
- if (recvmsg_from_client(servfd, &real_src_addr) == -1)
1526
+ if (recvmsg_from_client(servfd, &recvmsg_addr) == -1)
13141527 goto err;
13151528
1316
- if (cmp_addr(&real_src_addr, &expected_src_addr, /*cmp_port*/0))
1529
+ if (cmp_addr(&recvmsg_addr, &expected_addr, /*cmp_port*/0))
13171530 goto err;
13181531 }
13191532
....@@ -1346,6 +1559,9 @@
13461559 goto out;
13471560 } else if (test->expected_result == ATTACH_REJECT || err) {
13481561 goto err;
1562
+ } else if (test->expected_result == ATTACH_OKAY) {
1563
+ err = 0;
1564
+ goto out;
13491565 }
13501566
13511567 switch (test->attach_type) {
....@@ -1359,7 +1575,11 @@
13591575 break;
13601576 case BPF_CGROUP_UDP4_SENDMSG:
13611577 case BPF_CGROUP_UDP6_SENDMSG:
1362
- err = run_sendmsg_test_case(test);
1578
+ err = run_xmsg_test_case(test, 1);
1579
+ break;
1580
+ case BPF_CGROUP_UDP4_RECVMSG:
1581
+ case BPF_CGROUP_UDP6_RECVMSG:
1582
+ err = run_xmsg_test_case(test, 0);
13631583 break;
13641584 default:
13651585 goto err;
....@@ -1418,14 +1638,8 @@
14181638 exit(err);
14191639 }
14201640
1421
- if (setup_cgroup_environment())
1422
- goto err;
1423
-
1424
- cgfd = create_and_get_cgroup(CG_PATH);
1425
- if (!cgfd)
1426
- goto err;
1427
-
1428
- if (join_cgroup(CG_PATH))
1641
+ cgfd = cgroup_setup_and_join(CG_PATH);
1642
+ if (cgfd < 0)
14291643 goto err;
14301644
14311645 if (run_tests(cgfd))