mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 21:02:43 +01:00
Add BPF kfuncs that allow BPF LSM programs to create and use sockets for
sending data. This provides a mechanism for BPF programs to emit
telemetry. For this first patch set, it's restricted to SOCK_DGRAM
socket types with IPPROTO_UDP protocol but could be easily extended to
SOCK_STREAM and IPPROTO_TCP in the future.
The API consists of five kfuncs:
bpf_ksock_create() - Create a socket (sleepable)
bpf_ksock_connect() - Connect socket to remote address (sleepable)
bpf_ksock_send() - Send data through the socket (sleepable)
bpf_ksock_acquire() - Acquire a reference to a socket context
bpf_ksock_release() - Release a reference (cleanup via
queue_rcu_work since sock_release sleeps)
The setup kfuncs bpf_ksock_create, bpf_ksock_connect, can be called from
SYSCALL programs only. While bpf_ksock_acquire, bpf_ksock_release and
bpf_ksock_send can be called from SYSCALL and LSM programs.
The implementation follows the established kfunc lifecycle pattern
(create/acquire/release with refcounting, kptr map storage, dtor
registration). The kernel socket is wrapped in a refcounted bpf_ksock
struct. Cleanup is deferred via queue_rcu_work() because sock_release()
may sleep.
The kfuncs are only compiled when CONFIG_INET is enabled, as they
specifically support AF_INET and AF_INET6 sockets.
The socket operations go through the expected LSM hooks instead of
by-passing them like many kernel sockets since those are created by BPF
programs and thus system users. Thus, the bpf_ksock_send() kfunc, which
is exposed to LSM progs has a verifier filter protection to avoid
recursion so that the whole bpf_kfunc_set kfunc set cannot be called in
a program attached to security_socket_sendmsg(). Also, because of the
LSM checks, we prevent the use of the kfuncs from asynchronous workqueue
as the current value would then be invalid.
In bpf_ksock_create(), we copy the arg values to avoid TOCTOU races
since the kfunc can sleep and the arg values could be stored in a map
that could be re-written by BPF progs or even userspace programs if the
map is mmaped.
Signed-off-by: Mahe Tardy <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Reviewed-by: Jiayuan Chen <[email protected]>
Acked-by: Stanislav Fomichev <[email protected]>
Acked-by: Song Liu <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
37 lines
858 B
C
37 lines
858 B
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/* Copyright (c) 2026 Isovalent */
|
|
|
|
#ifndef _BPF_KSOCK_H
|
|
#define _BPF_KSOCK_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/in.h>
|
|
#include <linux/in6.h>
|
|
|
|
/**
|
|
* struct bpf_ksock_create_opts - BPF kernel socket creation parameters
|
|
* @family: Address family: AF_INET or AF_INET6.
|
|
* @type: Socket type: only SOCK_DGRAM supported for now.
|
|
* @protocol: Protocol number (e.g. IPPROTO_UDP), or 0 for the default protocol
|
|
* of the given type.
|
|
* @reserved: Must be zero. Reserved for future use.
|
|
*/
|
|
struct bpf_ksock_create_opts {
|
|
__u8 family;
|
|
__u8 type;
|
|
__u8 protocol;
|
|
__u8 reserved;
|
|
};
|
|
|
|
/**
|
|
* union bpf_ksock_addr - IPv4 or IPv6 socket address
|
|
* @sin: IPv4 socket address.
|
|
* @sin6: IPv6 socket address.
|
|
*/
|
|
union bpf_ksock_addr {
|
|
struct sockaddr_in sin;
|
|
struct sockaddr_in6 sin6;
|
|
};
|
|
|
|
#endif /* _BPF_KSOCK_H */
|