Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -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)
		}
		}
	}
	}


	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;
+50 −3
Original line number Original line Diff line number Diff line
@@ -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);
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[] = {
		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)
	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)
	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);