diff mbox series

[bpf-next,v3,3/9] bpf: Add bpf_sock_addr_set() to allow writing sockaddr len from bpf

Message ID 20230829101838.851350-4-daan.j.demeyer@gmail.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series Add cgroup sockaddr hooks for unix sockets | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-0 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-5 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-1 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-17 fail Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 fail Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 fail Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 fail Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 fail Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 fail Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 fail Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-28 fail Logs for veristat
bpf/vmtest-bpf-next-VM_Test-10 fail Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 fail Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-12 fail Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 fail Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 fail Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 fail Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-15 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 fail Logs for test_maps on s390x with gcc
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 1360 this patch: 1362
netdev/cc_maintainers warning 16 maintainers not CCed: kuba@kernel.org hawk@kernel.org daniel@iogearbox.net netdev@vger.kernel.org kpsingh@kernel.org john.fastabend@gmail.com sdf@google.com song@kernel.org andrii@kernel.org yonghong.song@linux.dev jolsa@kernel.org davem@davemloft.net pabeni@redhat.com haoluo@google.com ast@kernel.org edumazet@google.com
netdev/build_clang fail Errors and warnings before: 1353 this patch: 1355
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 1383 this patch: 1385
netdev/checkpatch warning WARNING: line length of 86 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Daan De Meyer Aug. 29, 2023, 10:18 a.m. UTC
As prep for adding unix socket support to the cgroup sockaddr hooks,
let's add a kfunc bpf_sock_addr_set() that allows modifying a sockaddr
from bpf. While this is already possible for AF_INET and AF_INET6, we'll
need this kfunc when we add unix socket support since modifying the
address for those requires modifying both the address and the sockaddr
length.

We also add the necessary hook to make the new kfunc work properly.

Signed-off-by: Daan De Meyer <daan.j.demeyer@gmail.com>
---
 kernel/bpf/btf.c  |  3 +++
 net/core/filter.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)

Comments

Alexei Starovoitov Aug. 29, 2023, 5:42 p.m. UTC | #1
On Tue, Aug 29, 2023 at 3:19 AM Daan De Meyer <daan.j.demeyer@gmail.com> wrote:
>
> As prep for adding unix socket support to the cgroup sockaddr hooks,
> let's add a kfunc bpf_sock_addr_set() that allows modifying a sockaddr
> from bpf. While this is already possible for AF_INET and AF_INET6, we'll
> need this kfunc when we add unix socket support since modifying the
> address for those requires modifying both the address and the sockaddr
> length.
>
> We also add the necessary hook to make the new kfunc work properly.
>
> Signed-off-by: Daan De Meyer <daan.j.demeyer@gmail.com>
> ---
>  kernel/bpf/btf.c  |  3 +++
>  net/core/filter.c | 42 +++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 249657c466dd..157342eaa2bb 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -217,6 +217,7 @@ enum btf_kfunc_hook {
>         m,
>         BTF_KFUNC_HOOK_LWT,
>         BTF_KFUNC_HOOK_NETFILTER,
> +       BTF_KFUNC_HOOK_SOCK_ADDR,

Do we really need a new kfunc category?
Can BTF_KFUNC_HOOK_CGROUP_SKB be reused here?
or even BTF_KFUNC_HOOK_COMMON ?

struct bpf_sock_addr_kern * type of bpf_sock_addr_set_addr()
will prevent any other type being passed in here
and bpf_sock_addr_kern type is local to prog
run via __cgroup_bpf_run_filter_sock_addr.
Martin KaFai Lau Aug. 30, 2023, 6:28 a.m. UTC | #2
On 8/29/23 3:18 AM, Daan De Meyer wrote:
> +__bpf_kfunc int bpf_sock_addr_set_addr(struct bpf_sock_addr_kern *sa_kern,
> +				       const u8 *addr, u32 addrlen__sz)
> +{
> +	struct sockaddr *sa = sa_kern->uaddr;
> +	struct sockaddr_in *sa4;
> +	struct sockaddr_in6 *sa6;
> +	struct sockaddr_un *un;
> +
> +	switch (sa->sa_family) {

The sa_family could be AF_UNSPEC here for inet addr (eg. take a look at 
__inet_bind checking AF_UNSPEC). Test the sa_kern->sk->sk_family instead.

> +	case AF_INET:
> +		if (addrlen__sz != 4)
> +			return -EINVAL;
> +		sa4 = (struct sockaddr_in *)sa;
> +		sa4->sin_addr.s_addr = *(__be32 *)addr;
> +		break;
> +	case AF_INET6:
> +		if (addrlen__sz != 16)
> +			return -EINVAL;
> +		sa6 = (struct sockaddr_in6 *)sa;
> +		memcpy(sa6->sin6_addr.s6_addr, addr, 16);
> +		break;
> +	default:
> +		WARN_ON_ONCE(1);

The above switch case will test sk_family instead, so this WARN should never 
happen and should be removed.

> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
>   __diag_pop();
diff mbox series

Patch

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 249657c466dd..157342eaa2bb 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -217,6 +217,7 @@  enum btf_kfunc_hook {
 	BTF_KFUNC_HOOK_SOCKET_FILTER,
 	BTF_KFUNC_HOOK_LWT,
 	BTF_KFUNC_HOOK_NETFILTER,
+	BTF_KFUNC_HOOK_SOCK_ADDR,
 	BTF_KFUNC_HOOK_MAX,
 };
 
@@ -7846,6 +7847,8 @@  static int bpf_prog_type_to_kfunc_hook(enum bpf_prog_type prog_type)
 		return BTF_KFUNC_HOOK_LWT;
 	case BPF_PROG_TYPE_NETFILTER:
 		return BTF_KFUNC_HOOK_NETFILTER;
+	case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
+		return BTF_KFUNC_HOOK_SOCK_ADDR;
 	default:
 		return BTF_KFUNC_HOOK_MAX;
 	}
diff --git a/net/core/filter.c b/net/core/filter.c
index a094694899c9..c58c3cd2cd55 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -11752,6 +11752,35 @@  __bpf_kfunc int bpf_dynptr_from_xdp(struct xdp_buff *xdp, u64 flags,
 
 	return 0;
 }
+
+__bpf_kfunc int bpf_sock_addr_set_addr(struct bpf_sock_addr_kern *sa_kern,
+				       const u8 *addr, u32 addrlen__sz)
+{
+	struct sockaddr *sa = sa_kern->uaddr;
+	struct sockaddr_in *sa4;
+	struct sockaddr_in6 *sa6;
+	struct sockaddr_un *un;
+
+	switch (sa->sa_family) {
+	case AF_INET:
+		if (addrlen__sz != 4)
+			return -EINVAL;
+		sa4 = (struct sockaddr_in *)sa;
+		sa4->sin_addr.s_addr = *(__be32 *)addr;
+		break;
+	case AF_INET6:
+		if (addrlen__sz != 16)
+			return -EINVAL;
+		sa6 = (struct sockaddr_in6 *)sa;
+		memcpy(sa6->sin6_addr.s6_addr, addr, 16);
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return -EINVAL;
+	}
+
+	return 0;
+}
 __diag_pop();
 
 int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags,
@@ -11776,6 +11805,10 @@  BTF_SET8_START(bpf_kfunc_check_set_xdp)
 BTF_ID_FLAGS(func, bpf_dynptr_from_xdp)
 BTF_SET8_END(bpf_kfunc_check_set_xdp)
 
+BTF_SET8_START(bpf_kfunc_check_set_sock_addr)
+BTF_ID_FLAGS(func, bpf_sock_addr_set_addr)
+BTF_SET8_END(bpf_kfunc_check_set_sock_addr)
+
 static const struct btf_kfunc_id_set bpf_kfunc_set_skb = {
 	.owner = THIS_MODULE,
 	.set = &bpf_kfunc_check_set_skb,
@@ -11786,6 +11819,11 @@  static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = {
 	.set = &bpf_kfunc_check_set_xdp,
 };
 
+static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = {
+	.owner = THIS_MODULE,
+	.set = &bpf_kfunc_check_set_sock_addr,
+};
+
 static int __init bpf_kfunc_init(void)
 {
 	int ret;
@@ -11800,7 +11838,9 @@  static int __init bpf_kfunc_init(void)
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_XMIT, &bpf_kfunc_set_skb);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_SEG6LOCAL, &bpf_kfunc_set_skb);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb);
-	return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp);
+	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp);
+	return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
+						&bpf_kfunc_set_sock_addr);
 }
 late_initcall(bpf_kfunc_init);