Skip to content

Commit 466f89e

Browse files
author
Alexei Starovoitov
committed
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>
2 parents ec90ad3 + 976b4f3 commit 466f89e

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

net/ipv6/udp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,10 +1390,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
13901390
ipc6.opt = opt;
13911391

13921392
fl6.flowi6_proto = sk->sk_protocol;
1393-
if (!ipv6_addr_any(daddr))
1394-
fl6.daddr = *daddr;
1395-
else
1396-
fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
1393+
fl6.daddr = *daddr;
13971394
if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
13981395
fl6.saddr = np->saddr;
13991396
fl6.fl6_sport = inet->inet_sport;
@@ -1421,6 +1418,9 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
14211418
}
14221419
}
14231420

1421+
if (ipv6_addr_any(&fl6.daddr))
1422+
fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
1423+
14241424
final_p = fl6_update_dst(&fl6, opt, &final);
14251425
if (final_p)
14261426
connected = false;

tools/testing/selftests/bpf/test_sock_addr.c

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define SERV6_V4MAPPED_IP "::ffff:192.168.0.4"
4545
#define SRC6_IP "::1"
4646
#define SRC6_REWRITE_IP "::6"
47+
#define WILDCARD6_IP "::"
4748
#define SERV6_PORT 6060
4849
#define SERV6_REWRITE_PORT 6666
4950

@@ -85,12 +86,14 @@ static int bind4_prog_load(const struct sock_addr_test *test);
8586
static int bind6_prog_load(const struct sock_addr_test *test);
8687
static int connect4_prog_load(const struct sock_addr_test *test);
8788
static int connect6_prog_load(const struct sock_addr_test *test);
89+
static int sendmsg_allow_prog_load(const struct sock_addr_test *test);
8890
static int sendmsg_deny_prog_load(const struct sock_addr_test *test);
8991
static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test);
9092
static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test);
9193
static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test);
9294
static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test);
9395
static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test);
96+
static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test);
9497

9598
static struct sock_addr_test tests[] = {
9699
/* bind */
@@ -462,6 +465,34 @@ static struct sock_addr_test tests[] = {
462465
SRC6_REWRITE_IP,
463466
SYSCALL_ENOTSUPP,
464467
},
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+
},
465496
{
466497
"sendmsg6: deny call",
467498
sendmsg_deny_prog_load,
@@ -734,16 +765,27 @@ static int connect6_prog_load(const struct sock_addr_test *test)
734765
return load_path(test, CONNECT6_PROG_PATH);
735766
}
736767

737-
static int sendmsg_deny_prog_load(const struct sock_addr_test *test)
768+
static int sendmsg_ret_only_prog_load(const struct sock_addr_test *test,
769+
int32_t rc)
738770
{
739771
struct bpf_insn insns[] = {
740-
/* return 0 */
741-
BPF_MOV64_IMM(BPF_REG_0, 0),
772+
/* return rc */
773+
BPF_MOV64_IMM(BPF_REG_0, rc),
742774
BPF_EXIT_INSN(),
743775
};
744776
return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
745777
}
746778

779+
static int sendmsg_allow_prog_load(const struct sock_addr_test *test)
780+
{
781+
return sendmsg_ret_only_prog_load(test, /*rc*/ 1);
782+
}
783+
784+
static int sendmsg_deny_prog_load(const struct sock_addr_test *test)
785+
{
786+
return sendmsg_ret_only_prog_load(test, /*rc*/ 0);
787+
}
788+
747789
static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test)
748790
{
749791
struct sockaddr_in dst4_rw_addr;
@@ -864,6 +906,11 @@ static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test)
864906
return sendmsg6_rw_dst_asm_prog_load(test, SERV6_V4MAPPED_IP);
865907
}
866908

909+
static 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+
867914
static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test)
868915
{
869916
return load_path(test, SENDMSG6_PROG_PATH);

0 commit comments

Comments
 (0)