Message ID | 20231006074530.892825-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 |
From: Daan De Meyer <daan.j.demeyer@gmail.com> Date: Fri, 6 Oct 2023 09:44:57 +0200 > As prep for adding unix socket support to the cgroup sockaddr hooks, > let's add a kfunc bpf_sock_addr_set_unix_addr() 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. > > Signed-off-by: Daan De Meyer <daan.j.demeyer@gmail.com> > --- > kernel/bpf/btf.c | 1 + > net/core/filter.c | 34 +++++++++++++++++++++++++++++++++- > 2 files changed, 34 insertions(+), 1 deletion(-) > > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index 69101200c124..15d71d2986d3 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c > @@ -7850,6 +7850,7 @@ static int bpf_prog_type_to_kfunc_hook(enum bpf_prog_type prog_type) > case BPF_PROG_TYPE_SYSCALL: > return BTF_KFUNC_HOOK_SYSCALL; > case BPF_PROG_TYPE_CGROUP_SKB: > + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: > return BTF_KFUNC_HOOK_CGROUP_SKB; > case BPF_PROG_TYPE_SCHED_ACT: > return BTF_KFUNC_HOOK_SCHED_ACT; > diff --git a/net/core/filter.c b/net/core/filter.c > index a094694899c9..bd1c42b28483 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); > @@ -11752,6 +11753,26 @@ __bpf_kfunc int bpf_dynptr_from_xdp(struct xdp_buff *xdp, u64 flags, > > return 0; > } > + > +__bpf_kfunc int bpf_sock_addr_set_unix_addr(struct bpf_sock_addr_kern *sa_kern, > + const u8 *addr, u32 addrlen__sz) I'd rename addrlen__sz to sun_path_len or something else because the conventional addrlen for AF_UNIX contains offsetof(struct sockaddr_un, sun_path). Also it would be good to document that the length is of sun_path[]. > +{ > + struct sockaddr *sa = sa_kern->uaddr; > + struct sockaddr_un *un; > + > + if (sa_kern->sk->sk_family != AF_UNIX) > + return -EINVAL; > + > + /* We do not allow changing the address of unnamed unix sockets. */ This comment is slightly confusing as addrlen__sz is a user-specified value for destination address of named sockets except for getsockname(). So, probably we can just remove the comment. (or s/of/to/ ?) > + if (addrlen__sz == 0 || addrlen__sz > UNIX_PATH_MAX) > + return -EINVAL; > + > + un = (struct sockaddr_un *)sa; > + memcpy(un->sun_path, addr, addrlen__sz); > + sa_kern->uaddrlen = offsetof(struct sockaddr_un, sun_path) + addrlen__sz; > + > + return 0; > +} > __diag_pop(); > > int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags, > @@ -11776,6 +11797,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_unix_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 +11811,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 +11830,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); > > -- > 2.41.0
On 10/10/23 10:00 AM, Kuniyuki Iwashima wrote: >> +__bpf_kfunc int bpf_sock_addr_set_unix_addr(struct bpf_sock_addr_kern *sa_kern, >> + const u8 *addr, u32 addrlen__sz) > I'd rename addrlen__sz to sun_path_len or something else because the > conventional addrlen for AF_UNIX contains offsetof(struct sockaddr_un, > sun_path). The "__sz" suffix is required by the verifier. It is the size of the preceding argument "addr". While at it, addrlen__sz should be just "addr__sz" (or sun_path__sz, depending on what name is decided here) for consistency with other kfunc. I don't have strong preference on the argument name. However, if it is sun_path__sz, then the preceding argument should be renamed to "sun_path" also for consistency reason and then the kfunc should probably be renamed to bpf_sock_addr_set_sun_path.
From: Martin KaFai Lau <martin.lau@linux.dev> Date: Tue, 10 Oct 2023 13:07:54 -0700 > On 10/10/23 10:00 AM, Kuniyuki Iwashima wrote: > >> +__bpf_kfunc int bpf_sock_addr_set_unix_addr(struct bpf_sock_addr_kern *sa_kern, > >> + const u8 *addr, u32 addrlen__sz) > > I'd rename addrlen__sz to sun_path_len or something else because the > > conventional addrlen for AF_UNIX contains offsetof(struct sockaddr_un, > > sun_path). > > The "__sz" suffix is required by the verifier. It is the size of the preceding > argument "addr". While at it, addrlen__sz should be just "addr__sz" (or > sun_path__sz, depending on what name is decided here) for consistency with other > kfunc. I didn't know that, thank you! > > I don't have strong preference on the argument name. However, if it is > sun_path__sz, then the preceding argument should be renamed to "sun_path" also > for consistency reason and then the kfunc should probably be renamed to > bpf_sock_addr_set_sun_path. I prefer sun_path, sun_path__sz, and bpf_sock_addr_set_sun_path() that are clearer and consistent with uAPI, sockaddr_un.sun_path.
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 69101200c124..15d71d2986d3 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -7850,6 +7850,7 @@ static int bpf_prog_type_to_kfunc_hook(enum bpf_prog_type prog_type) case BPF_PROG_TYPE_SYSCALL: return BTF_KFUNC_HOOK_SYSCALL; case BPF_PROG_TYPE_CGROUP_SKB: + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: return BTF_KFUNC_HOOK_CGROUP_SKB; case BPF_PROG_TYPE_SCHED_ACT: return BTF_KFUNC_HOOK_SCHED_ACT; diff --git a/net/core/filter.c b/net/core/filter.c index a094694899c9..bd1c42b28483 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); @@ -11752,6 +11753,26 @@ __bpf_kfunc int bpf_dynptr_from_xdp(struct xdp_buff *xdp, u64 flags, return 0; } + +__bpf_kfunc int bpf_sock_addr_set_unix_addr(struct bpf_sock_addr_kern *sa_kern, + const u8 *addr, u32 addrlen__sz) +{ + struct sockaddr *sa = sa_kern->uaddr; + struct sockaddr_un *un; + + if (sa_kern->sk->sk_family != AF_UNIX) + return -EINVAL; + + /* We do not allow changing the address of unnamed unix sockets. */ + if (addrlen__sz == 0 || addrlen__sz > UNIX_PATH_MAX) + return -EINVAL; + + un = (struct sockaddr_un *)sa; + memcpy(un->sun_path, addr, addrlen__sz); + sa_kern->uaddrlen = offsetof(struct sockaddr_un, sun_path) + addrlen__sz; + + return 0; +} __diag_pop(); int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags, @@ -11776,6 +11797,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_unix_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 +11811,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 +11830,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);
As prep for adding unix socket support to the cgroup sockaddr hooks, let's add a kfunc bpf_sock_addr_set_unix_addr() 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. Signed-off-by: Daan De Meyer <daan.j.demeyer@gmail.com> --- kernel/bpf/btf.c | 1 + net/core/filter.c | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-)