Message ID | 20221210193559.371515-4-daan.j.demeyer@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | Add cgroup sockaddr hooks for unix sockets | expand |
On 12/10/22 11:35 AM, Daan De Meyer wrote: > Preparation for adding unix support to cgroup sockaddr bpf programs. > In this commit, no programs are allowed to access user_path. We'll > open this up to the new unix program types in a later commit. > --- > include/uapi/linux/bpf.h | 1 + > net/core/filter.c | 19 +++++++++++++++++++ > tools/include/uapi/linux/bpf.h | 1 + > 3 files changed, 21 insertions(+) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index 7cafcfdbb9b2..9e3c33f83bba 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -6366,6 +6366,7 @@ struct bpf_sock_addr { > * Stored in network byte order. > */ > __bpf_md_ptr(struct bpf_sock *, sk); > + char user_path[108]; /* Allows 1 byte read and write. */ > __u32 user_addrlen; /* Allows 4 byte read and write. */ > }; Ideally, for bisecting reason, it would be great to add user_path first and then user_addrlen second. Otherwise, some tests utilizing user_addrlen might not run correctly with Patch 2/9. > > diff --git a/net/core/filter.c b/net/core/filter.c > index d0620927dbca..cc86b38fc764 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -26,6 +26,7 @@ > #include <linux/socket.h> > #include <linux/sock_diag.h> > #include <linux/in.h> > +#include <linux/un.h> > #include <linux/inet.h> > #include <linux/netdevice.h> > #include <linux/if_packet.h> [...]
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 7cafcfdbb9b2..9e3c33f83bba 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -6366,6 +6366,7 @@ struct bpf_sock_addr { * Stored in network byte order. */ __bpf_md_ptr(struct bpf_sock *, sk); + char user_path[108]; /* Allows 1 byte read and write. */ __u32 user_addrlen; /* Allows 4 byte read and write. */ }; diff --git a/net/core/filter.c b/net/core/filter.c index d0620927dbca..cc86b38fc764 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -26,6 +26,7 @@ #include <linux/socket.h> #include <linux/sock_diag.h> #include <linux/in.h> +#include <linux/un.h> #include <linux/inet.h> #include <linux/netdevice.h> #include <linux/if_packet.h> @@ -8830,6 +8831,8 @@ static bool sock_addr_is_valid_access(int off, int size, return false; } break; + case bpf_ctx_range_till(struct bpf_sock_addr, user_path[0], user_path[107]): + return false; } switch (off) { @@ -8876,6 +8879,10 @@ static bool sock_addr_is_valid_access(int off, int size, return false; info->reg_type = PTR_TO_SOCKET; break; + case bpf_ctx_range_till(struct bpf_sock_addr, user_path[0], user_path[107]): + if (size != sizeof(char)) + return false; + break; case bpf_ctx_range(struct bpf_sock_addr, user_addrlen): if (type != BPF_READ) return false; @@ -9995,6 +10002,18 @@ static u32 sock_addr_convert_ctx_access(enum bpf_access_type type, offsetof(struct bpf_sock_addr_kern, sk)); break; + case bpf_ctx_range_till(struct bpf_sock_addr, user_path[0], user_path[107]): + /* In kernelspace, addresses are always stored in + * sockaddr_storage so any access in the full range of + * sockaddr_un.sun_path is safe. + */ + off = si->off; + off -= offsetof(struct bpf_sock_addr, user_path[0]); + SOCK_ADDR_LOAD_OR_STORE_NESTED_FIELD_SIZE_OFF( + struct bpf_sock_addr_kern, struct sockaddr_un, uaddr, + sun_path, BPF_SIZE(si->code), off, tmp_reg); + break; + case offsetof(struct bpf_sock_addr, user_addrlen): /* uaddrlen is a pointer so it should be accessed via indirect * loads and stores. Also for stores additional temporary diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 7cafcfdbb9b2..9e3c33f83bba 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -6366,6 +6366,7 @@ struct bpf_sock_addr { * Stored in network byte order. */ __bpf_md_ptr(struct bpf_sock *, sk); + char user_path[108]; /* Allows 1 byte read and write. */ __u32 user_addrlen; /* Allows 4 byte read and write. */ };