Add defensive size validation to bpf_sock_addr_set_sun_path() before writing to the sockaddr buffer. While the underlying buffer is guaranteed to be sockaddr_storage (128 bytes) from the bind() syscall path, the function should validate that "sa_kern->uaddrlen" is sufficient for the sockaddr_un structure being written. The validation checks that the available buffer size ("sa_kern->uaddrlen") can accommodate both the sockaddr_un header and the requested path length before performing the memcpy() operation. Signed-off-by: Kees Cook --- net/core/filter.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/core/filter.c b/net/core/filter.c index b96b5ffc7eb3..fa6c5baf0bf3 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12089,6 +12089,7 @@ __bpf_kfunc int bpf_sock_addr_set_sun_path(struct bpf_sock_addr_kern *sa_kern, const u8 *sun_path, u32 sun_path__sz) { struct sockaddr_un *un; + size_t required_size; if (sa_kern->sk->sk_family != AF_UNIX) return -EINVAL; @@ -12099,9 +12100,14 @@ __bpf_kfunc int bpf_sock_addr_set_sun_path(struct bpf_sock_addr_kern *sa_kern, if (sun_path__sz == 0 || sun_path__sz > UNIX_PATH_MAX) return -EINVAL; + /* Validate that the buffer is large enough for sockaddr_un + path */ + required_size = offsetof(struct sockaddr_un, sun_path) + sun_path__sz; + if (sa_kern->uaddrlen < required_size) + return -EINVAL; + un = (struct sockaddr_un *)sa_kern->uaddr; memcpy(un->sun_path, sun_path, sun_path__sz); - sa_kern->uaddrlen = offsetof(struct sockaddr_un, sun_path) + sun_path__sz; + sa_kern->uaddrlen = required_size; return 0; } -- 2.34.1