aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2019-01-04 23:23:33 -0500
committerAlexei Starovoitov <ast@kernel.org>2019-01-04 23:23:34 -0500
commit466f89e9ec8c6868131c2d2ba9cd5f536879c42a (patch)
tree34278582594c9b6909bab6005a955521dc3d4ee1
parentec90ad334986fa5856d11dd272f7f22fa86c55c4 (diff)
parent976b4f3a4646fbf0d189caca25f91f82e4be4b5a (diff)
Merge branch 'udpv6_sendmsg-addr_any-fix'
Andrey Ignatov says: ==================== The patch set fixes BSD'ism in sys_sendmsg to rewrite unspecified destination IPv6 for unconnected UDP sockets in sys_sendmsg with [::1] in case when either CONFIG_CGROUP_BPF is enabled or when sys_sendmsg BPF hook sets destination IPv6 to [::]. Patch 1 is the fix and provides more details. Patch 2 adds two test cases to verify the fix. v1->v2: * Fix compile error in patch 1. ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r--net/ipv6/udp.c8
-rw-r--r--tools/testing/selftests/bpf/test_sock_addr.c53
2 files changed, 54 insertions, 7 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 9cbf363172bd..7c3505006f8e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1390,10 +1390,7 @@ do_udp_sendmsg:
1390 ipc6.opt = opt; 1390 ipc6.opt = opt;
1391 1391
1392 fl6.flowi6_proto = sk->sk_protocol; 1392 fl6.flowi6_proto = sk->sk_protocol;
1393 if (!ipv6_addr_any(daddr)) 1393 fl6.daddr = *daddr;
1394 fl6.daddr = *daddr;
1395 else
1396 fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
1397 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) 1394 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
1398 fl6.saddr = np->saddr; 1395 fl6.saddr = np->saddr;
1399 fl6.fl6_sport = inet->inet_sport; 1396 fl6.fl6_sport = inet->inet_sport;
@@ -1421,6 +1418,9 @@ do_udp_sendmsg:
1421 } 1418 }
1422 } 1419 }
1423 1420
1421 if (ipv6_addr_any(&fl6.daddr))
1422 fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
1423
1424 final_p = fl6_update_dst(&fl6, opt, &final); 1424 final_p = fl6_update_dst(&fl6, opt, &final);
1425 if (final_p) 1425 if (final_p)
1426 connected = false; 1426 connected = false;
diff --git a/tools/testing/selftests/bpf/test_sock_addr.c b/tools/testing/selftests/bpf/test_sock_addr.c
index 73b7493d4120..d94336cbd8bd 100644
--- a/tools/testing/selftests/bpf/test_sock_addr.c
+++ b/tools/testing/selftests/bpf/test_sock_addr.c
@@ -44,6 +44,7 @@
44#define SERV6_V4MAPPED_IP "::ffff:192.168.0.4" 44#define SERV6_V4MAPPED_IP "::ffff:192.168.0.4"
45#define SRC6_IP "::1" 45#define SRC6_IP "::1"
46#define SRC6_REWRITE_IP "::6" 46#define SRC6_REWRITE_IP "::6"
47#define WILDCARD6_IP "::"
47#define SERV6_PORT 6060 48#define SERV6_PORT 6060
48#define SERV6_REWRITE_PORT 6666 49#define SERV6_REWRITE_PORT 6666
49 50
@@ -85,12 +86,14 @@ static int bind4_prog_load(const struct sock_addr_test *test);
85static int bind6_prog_load(const struct sock_addr_test *test); 86static int bind6_prog_load(const struct sock_addr_test *test);
86static int connect4_prog_load(const struct sock_addr_test *test); 87static int connect4_prog_load(const struct sock_addr_test *test);
87static int connect6_prog_load(const struct sock_addr_test *test); 88static int connect6_prog_load(const struct sock_addr_test *test);
89static int sendmsg_allow_prog_load(const struct sock_addr_test *test);
88static int sendmsg_deny_prog_load(const struct sock_addr_test *test); 90static int sendmsg_deny_prog_load(const struct sock_addr_test *test);
89static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test); 91static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test);
90static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test); 92static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test);
91static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test); 93static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test);
92static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test); 94static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test);
93static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test); 95static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test);
96static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test);
94 97
95static struct sock_addr_test tests[] = { 98static struct sock_addr_test tests[] = {
96 /* bind */ 99 /* bind */
@@ -463,6 +466,34 @@ static struct sock_addr_test tests[] = {
463 SYSCALL_ENOTSUPP, 466 SYSCALL_ENOTSUPP,
464 }, 467 },
465 { 468 {
469 "sendmsg6: set dst IP = [::] (BSD'ism)",
470 sendmsg6_rw_wildcard_prog_load,
471 BPF_CGROUP_UDP6_SENDMSG,
472 BPF_CGROUP_UDP6_SENDMSG,
473 AF_INET6,
474 SOCK_DGRAM,
475 SERV6_IP,
476 SERV6_PORT,
477 SERV6_REWRITE_IP,
478 SERV6_REWRITE_PORT,
479 SRC6_REWRITE_IP,
480 SUCCESS,
481 },
482 {
483 "sendmsg6: preserve dst IP = [::] (BSD'ism)",
484 sendmsg_allow_prog_load,
485 BPF_CGROUP_UDP6_SENDMSG,
486 BPF_CGROUP_UDP6_SENDMSG,
487 AF_INET6,
488 SOCK_DGRAM,
489 WILDCARD6_IP,
490 SERV6_PORT,
491 SERV6_REWRITE_IP,
492 SERV6_PORT,
493 SRC6_IP,
494 SUCCESS,
495 },
496 {
466 "sendmsg6: deny call", 497 "sendmsg6: deny call",
467 sendmsg_deny_prog_load, 498 sendmsg_deny_prog_load,
468 BPF_CGROUP_UDP6_SENDMSG, 499 BPF_CGROUP_UDP6_SENDMSG,
@@ -734,16 +765,27 @@ static int connect6_prog_load(const struct sock_addr_test *test)
734 return load_path(test, CONNECT6_PROG_PATH); 765 return load_path(test, CONNECT6_PROG_PATH);
735} 766}
736 767
737static int sendmsg_deny_prog_load(const struct sock_addr_test *test) 768static int sendmsg_ret_only_prog_load(const struct sock_addr_test *test,
769 int32_t rc)
738{ 770{
739 struct bpf_insn insns[] = { 771 struct bpf_insn insns[] = {
740 /* return 0 */ 772 /* return rc */
741 BPF_MOV64_IMM(BPF_REG_0, 0), 773 BPF_MOV64_IMM(BPF_REG_0, rc),
742 BPF_EXIT_INSN(), 774 BPF_EXIT_INSN(),
743 }; 775 };
744 return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn)); 776 return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
745} 777}
746 778
779static int sendmsg_allow_prog_load(const struct sock_addr_test *test)
780{
781 return sendmsg_ret_only_prog_load(test, /*rc*/ 1);
782}
783
784static int sendmsg_deny_prog_load(const struct sock_addr_test *test)
785{
786 return sendmsg_ret_only_prog_load(test, /*rc*/ 0);
787}
788
747static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test) 789static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test)
748{ 790{
749 struct sockaddr_in dst4_rw_addr; 791 struct sockaddr_in dst4_rw_addr;
@@ -864,6 +906,11 @@ static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test)
864 return sendmsg6_rw_dst_asm_prog_load(test, SERV6_V4MAPPED_IP); 906 return sendmsg6_rw_dst_asm_prog_load(test, SERV6_V4MAPPED_IP);
865} 907}
866 908
909static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test)
910{
911 return sendmsg6_rw_dst_asm_prog_load(test, WILDCARD6_IP);
912}
913
867static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test) 914static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test)
868{ 915{
869 return load_path(test, SENDMSG6_PROG_PATH); 916 return load_path(test, SENDMSG6_PROG_PATH);