As prep for adding unix socket support to the cgroup sockaddr hooks, let's add a kfunc bpf_sock_addr_set() that allows modifying the sockaddr length from bpf. This is required to allow modifying AF_UNIX sockaddrs correctly. Signed-off-by: Daan De Meyer <daan.j.demeyer@xxxxxxxxx> --- net/core/filter.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/net/core/filter.c b/net/core/filter.c index 44fb997434ad..1c656e2d7b58 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -81,6 +81,7 @@ #include <net/xdp.h> #include <net/mptcp.h> #include <net/netfilter/nf_conntrack_bpf.h> +#include <linux/un.h> static const struct bpf_func_proto * bpf_sk_base_func_proto(enum bpf_func_id func_id); @@ -11670,6 +11671,44 @@ __bpf_kfunc int bpf_dynptr_from_xdp(struct xdp_buff *xdp, u64 flags, return 0; } + +__bpf_kfunc int bpf_sock_addr_set(struct bpf_sock_addr_kern *sa_kern, + const void *addr, u32 addrlen__sz) +{ + const struct sockaddr *sa = addr; + + if (addrlen__sz <= offsetof(struct sockaddr, sa_family)) + return -EINVAL; + + if (addrlen__sz > sizeof(struct sockaddr_storage)) + return -EINVAL; + + if (sa->sa_family != sa_kern->uaddr->sa_family) + return -EINVAL; + + switch (sa->sa_family) { + case AF_INET: + if (addrlen__sz < sizeof(struct sockaddr_in)) + return -EINVAL; + break; + case AF_INET6: + if (addrlen__sz < SIN6_LEN_RFC2133) + return -EINVAL; + break; + case AF_UNIX: + if (addrlen__sz <= offsetof(struct sockaddr_un, sun_path) || + addrlen__sz > sizeof(struct sockaddr_un)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + memcpy(sa_kern->uaddr, sa, addrlen__sz); + sa_kern->uaddrlen = addrlen__sz; + + return 0; +} __diag_pop(); int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags, @@ -11694,6 +11733,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) +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, @@ -11704,6 +11747,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; @@ -11717,6 +11765,8 @@ static int __init bpf_kfunc_init(void) ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_IN, &bpf_kfunc_set_skb); 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); - 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); -- 2.40.0