Commit 466f89e9 authored by Alexei Starovoitov's avatar Alexei Starovoitov

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: default avatarAlexei Starovoitov <ast@kernel.org>
parents ec90ad33 976b4f3a
...@@ -1390,10 +1390,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1390,10 +1390,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
ipc6.opt = opt; ipc6.opt = opt;
fl6.flowi6_proto = sk->sk_protocol; fl6.flowi6_proto = sk->sk_protocol;
if (!ipv6_addr_any(daddr)) fl6.daddr = *daddr;
fl6.daddr = *daddr;
else
fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
fl6.saddr = np->saddr; fl6.saddr = np->saddr;
fl6.fl6_sport = inet->inet_sport; fl6.fl6_sport = inet->inet_sport;
...@@ -1421,6 +1418,9 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1421,6 +1418,9 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
} }
} }
if (ipv6_addr_any(&fl6.daddr))
fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
final_p = fl6_update_dst(&fl6, opt, &final); final_p = fl6_update_dst(&fl6, opt, &final);
if (final_p) if (final_p)
connected = false; connected = false;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define SERV6_V4MAPPED_IP "::ffff:192.168.0.4" #define SERV6_V4MAPPED_IP "::ffff:192.168.0.4"
#define SRC6_IP "::1" #define SRC6_IP "::1"
#define SRC6_REWRITE_IP "::6" #define SRC6_REWRITE_IP "::6"
#define WILDCARD6_IP "::"
#define SERV6_PORT 6060 #define SERV6_PORT 6060
#define SERV6_REWRITE_PORT 6666 #define SERV6_REWRITE_PORT 6666
...@@ -85,12 +86,14 @@ static int bind4_prog_load(const struct sock_addr_test *test); ...@@ -85,12 +86,14 @@ static int bind4_prog_load(const struct sock_addr_test *test);
static int bind6_prog_load(const struct sock_addr_test *test); static int bind6_prog_load(const struct sock_addr_test *test);
static int connect4_prog_load(const struct sock_addr_test *test); static int connect4_prog_load(const struct sock_addr_test *test);
static int connect6_prog_load(const struct sock_addr_test *test); static int connect6_prog_load(const struct sock_addr_test *test);
static int sendmsg_allow_prog_load(const struct sock_addr_test *test);
static int sendmsg_deny_prog_load(const struct sock_addr_test *test); static int sendmsg_deny_prog_load(const struct sock_addr_test *test);
static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test); static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test);
static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test); static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test);
static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test); static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test);
static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test); static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test);
static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test); static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test);
static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test);
static struct sock_addr_test tests[] = { static struct sock_addr_test tests[] = {
/* bind */ /* bind */
...@@ -462,6 +465,34 @@ static struct sock_addr_test tests[] = { ...@@ -462,6 +465,34 @@ static struct sock_addr_test tests[] = {
SRC6_REWRITE_IP, SRC6_REWRITE_IP,
SYSCALL_ENOTSUPP, SYSCALL_ENOTSUPP,
}, },
{
"sendmsg6: set dst IP = [::] (BSD'ism)",
sendmsg6_rw_wildcard_prog_load,
BPF_CGROUP_UDP6_SENDMSG,
BPF_CGROUP_UDP6_SENDMSG,
AF_INET6,
SOCK_DGRAM,
SERV6_IP,
SERV6_PORT,
SERV6_REWRITE_IP,
SERV6_REWRITE_PORT,
SRC6_REWRITE_IP,
SUCCESS,
},
{
"sendmsg6: preserve dst IP = [::] (BSD'ism)",
sendmsg_allow_prog_load,
BPF_CGROUP_UDP6_SENDMSG,
BPF_CGROUP_UDP6_SENDMSG,
AF_INET6,
SOCK_DGRAM,
WILDCARD6_IP,
SERV6_PORT,
SERV6_REWRITE_IP,
SERV6_PORT,
SRC6_IP,
SUCCESS,
},
{ {
"sendmsg6: deny call", "sendmsg6: deny call",
sendmsg_deny_prog_load, sendmsg_deny_prog_load,
...@@ -734,16 +765,27 @@ static int connect6_prog_load(const struct sock_addr_test *test) ...@@ -734,16 +765,27 @@ static int connect6_prog_load(const struct sock_addr_test *test)
return load_path(test, CONNECT6_PROG_PATH); return load_path(test, CONNECT6_PROG_PATH);
} }
static int sendmsg_deny_prog_load(const struct sock_addr_test *test) static int sendmsg_ret_only_prog_load(const struct sock_addr_test *test,
int32_t rc)
{ {
struct bpf_insn insns[] = { struct bpf_insn insns[] = {
/* return 0 */ /* return rc */
BPF_MOV64_IMM(BPF_REG_0, 0), BPF_MOV64_IMM(BPF_REG_0, rc),
BPF_EXIT_INSN(), BPF_EXIT_INSN(),
}; };
return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn)); return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
} }
static int sendmsg_allow_prog_load(const struct sock_addr_test *test)
{
return sendmsg_ret_only_prog_load(test, /*rc*/ 1);
}
static int sendmsg_deny_prog_load(const struct sock_addr_test *test)
{
return sendmsg_ret_only_prog_load(test, /*rc*/ 0);
}
static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test) static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test)
{ {
struct sockaddr_in dst4_rw_addr; struct sockaddr_in dst4_rw_addr;
...@@ -864,6 +906,11 @@ static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test) ...@@ -864,6 +906,11 @@ static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test)
return sendmsg6_rw_dst_asm_prog_load(test, SERV6_V4MAPPED_IP); return sendmsg6_rw_dst_asm_prog_load(test, SERV6_V4MAPPED_IP);
} }
static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test)
{
return sendmsg6_rw_dst_asm_prog_load(test, WILDCARD6_IP);
}
static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test) static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test)
{ {
return load_path(test, SENDMSG6_PROG_PATH); return load_path(test, SENDMSG6_PROG_PATH);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment