All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mahe Tardy <mahe.tardy@gmail.com>
To: Kuniyuki Iwashima <kuniyu@google.com>
Cc: andrew+netdev@lunn.ch, andrii@kernel.org, ast@kernel.org,
	bpf@vger.kernel.org, daniel@iogearbox.net, davem@davemloft.net,
	eddyz87@gmail.com, edumazet@google.com, john.fastabend@gmail.com,
	kuba@kernel.org, liamwisehart@meta.com, martin.lau@linux.dev,
	netdev@vger.kernel.org, pabeni@redhat.com, song@kernel.org
Subject: Re: [PATCH bpf-next 2/6] bpf: Add ksock kfuncs
Date: Tue, 7 Jul 2026 12:06:15 +0200	[thread overview]
Message-ID: <akzPl9lLtjcRFXxD@gmail.com> (raw)
In-Reply-To: <20260706230142.1691146-1-kuniyu@google.com>

On Mon, Jul 06, 2026 at 11:01:27PM +0000, Kuniyuki Iwashima wrote:
> From: Mahe Tardy <mahe.tardy@gmail.com>
> Date: Mon,  6 Jul 2026 09:35:21 +0000
> > diff --git a/net/core/bpf_ksock.c b/net/core/bpf_ksock.c
> [...]
> > +static bool bpf_ksock_send_enter(struct bpf_ksock_send_guard *guard)
> 
> Can we do this better with assigning a single bit to task_struct ?

Yes, that would be way simpler but I avoided touching task_struct. If we
are okay with that then it could be simplified.

> 
> > +{
> > +	struct bpf_ksock_send_guard *entry;
> > +	struct hlist_bl_node *pos;
> > +	struct bpf_ksock_send_bucket *bucket;
> > +
> > +	bucket = bpf_ksock_send_bucket(current);
> > +	hlist_bl_lock(&bucket->head);
> > +	hlist_bl_for_each_entry(entry, pos, &bucket->head, node) {
> > +		if (entry->task == current) {
> > +			hlist_bl_unlock(&bucket->head);
> > +			return false;
> > +		}
> > +	}
> > +
> > +	guard->task = current;
> > +	INIT_HLIST_BL_NODE(&guard->node);
> > +	hlist_bl_add_head(&guard->node, &bucket->head);
> > +	hlist_bl_unlock(&bucket->head);
> > +	return true;
> > +}
> > +
> > +static void bpf_ksock_send_exit(struct bpf_ksock_send_guard *guard)
> > +{
> > +	struct bpf_ksock_send_bucket *bucket;
> > +
> > +	bucket = bpf_ksock_send_bucket(guard->task);
> > +	hlist_bl_lock(&bucket->head);
> > +	hlist_bl_del(&guard->node);
> > +	hlist_bl_unlock(&bucket->head);
> > +}
> [...]
> > +__bpf_kfunc struct bpf_ksock *
> > +bpf_ksock_create(const struct bpf_ksock_create_opts *opts, u32 opts__sz,
> > +		 int *err__uninit)
> > +{
> > +	struct bpf_ksock_create_opts opts_copy;
> > +	struct bpf_ksock *ks;
> > +	struct net *net;
> > +	int err;
> > +
> > +	/*
> > +	 * sock_create() derives the network namespace, credentials, and cgroup
> > +	 * from current. Kernel threads, including BPF workqueue callbacks, do
> > +	 * not carry the context of the task that invoked the BPF program.
> > +	 */
> > +	if (!bpf_ksock_has_user_task_context()) {
> > +		err = -EOPNOTSUPP;
> > +		goto err_out;
> > +	}
> > +
> > +	if (!opts || opts__sz != sizeof(struct bpf_ksock_create_opts)) {
> > +		err = -EINVAL;
> > +		goto err_out;
> > +	}
> > +
> > +	opts_copy = (struct bpf_ksock_create_opts){
> > +		.family = READ_ONCE(opts->family),
> > +		.type = READ_ONCE(opts->type),
> > +		.protocol = READ_ONCE(opts->protocol),
> > +		.reserved = READ_ONCE(opts->reserved),
> > +	};
> > +
> > +	if (opts_copy.reserved) {
> > +		err = -EINVAL;
> > +		goto err_out;
> > +	}
> > +
> > +	if (opts_copy.family != AF_INET && opts_copy.family != AF_INET6) {
> > +		err = -EAFNOSUPPORT;
> > +		goto err_out;
> > +	}
> > +
> > +	if (opts_copy.type != SOCK_DGRAM) {
> > +		err = -EPROTONOSUPPORT;
> > +		goto err_out;
> > +	}
> > +
> > +	if (opts_copy.protocol != IPPROTO_UDP && opts_copy.protocol != 0) {
> > +		err = -EPROTONOSUPPORT;
> > +		goto err_out;
> > +	}
> > +
> > +	ks = kzalloc_obj(*ks);
> > +	if (!ks) {
> > +		err = -ENOMEM;
> > +		goto err_out;
> > +	}
> > +
> > +	net = current->nsproxy->net_ns;
> > +	if (!bpf_ksock_net_try_charge(net)) {
> > +		err = -ENOSPC;
> > +		goto err_free;
> > +	}
> > +
> > +	/*
> > +	 * Use the normal current-task socket path so LSM/cgroup policy,
> > +	 * socket labels, and the active netns reference match a socket(2)
> > +	 * created by the BPF program's caller.
> > +	 */
> > +	err = sock_create(opts_copy.family, opts_copy.type, opts_copy.protocol,
> > +			  &ks->sock);
> 
> This also triggers LSM in __sock_create() so needs the loop
> detection, no ?
> 
> Same for __sys_bind_socket() and __sys_connect_socket().

This should be okay as create/bind/connect can only be called from
SYSCALL progs and not LSM progs. We only care about recursion from the
kfuncs in the ksock_kfunc_btf_ids group which are also allowed from LSM
progs (release/acquire/send).

> 
> 
> > +	if (err)
> > +		goto err_uncharge;
> > +
> > +	ks->sock->sk->sk_rcvbuf = SOCK_MIN_RCVBUF;
> > +	ks->sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
> > +
> > +	refcount_set(&ks->usage, 1);
> > +	put_unaligned(0, err__uninit);
> > +	return ks;
> > +
> > +err_uncharge:
> > +	bpf_ksock_net_uncharge(net);
> > +err_free:
> > +	kfree(ks);
> > +err_out:
> > +	put_unaligned(err, err__uninit);
> > +	return NULL;
> > +}
> > +
> > +/**
> > + * bpf_ksock_bind() - Bind a BPF kernel socket to a local address.
> > + * @ks:		The BPF kernel socket context.
> > + * @opts:	Pointer to struct bpf_ksock_addr_opts with local address.
> > + * @opts__sz:	Size of the opts struct.
> > + *
> > + * Binds the socket to the specified local address and port.
> > + * This is optional; if not called, the kernel will auto-assign.
> > + *
> > + * This function may sleep while binding the socket, so it can only be used in
> > + * sleepable BPF programs (SYSCALL).
> > + *
> > + * Return: 0 on success, negative errno on error.
> > + */
> > +__bpf_kfunc int bpf_ksock_bind(struct bpf_ksock *ks,
> > +			       const struct bpf_ksock_addr_opts *opts,
> > +			       u32 opts__sz)
> > +{
> > +	struct sockaddr_storage addr = {};
> 
> nit: we don't need to initialise here since bpf_ksock_get_addr() does.

Ah actually I didn't know that compound literal in C would zero the rest
of the struct. Thanks, let's remove those two then.

> 
> > +	int addrlen;
> > +
> > +	if (!bpf_ksock_has_user_task_context())
> > +		return -EOPNOTSUPP;
> > +
> > +	addrlen = bpf_ksock_get_addr(opts, opts__sz, &addr);
> > +	if (addrlen < 0)
> > +		return addrlen;
> > +
> > +	return __sys_bind_socket(ks->sock, &addr, addrlen);
> > +}
> > +
> > +/**
> > + * bpf_ksock_connect() - Connect a BPF kernel socket to a remote address.
> > + * @ks:		The BPF kernel socket context.
> > + * @opts:	Pointer to struct bpf_ksock_addr_opts with remote address.
> > + * @opts__sz:	Size of the opts struct.
> > + *
> > + * Connects the socket to the specified remote address and port.
> > + *
> > + * This function may sleep while connecting the socket, so it can only be used
> > + * in sleepable BPF programs (SYSCALL).
> > + *
> > + * Return: 0 on success, negative errno on error.
> > + */
> > +__bpf_kfunc int bpf_ksock_connect(struct bpf_ksock *ks,
> > +				  const struct bpf_ksock_addr_opts *opts,
> > +				  u32 opts__sz)
> > +{
> > +	struct sockaddr_storage addr = {};
> 
> Same.

Noted


  reply	other threads:[~2026-07-07 10:06 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-06  9:35 [PATCH bpf-next 0/6] Introduce bpf_ksock Mahe Tardy
2026-07-06  9:35 ` [PATCH bpf-next 1/6] net: Add __sys_connect_socket() helper Mahe Tardy
2026-07-06  9:35 ` [PATCH bpf-next 2/6] bpf: Add ksock kfuncs Mahe Tardy
2026-07-06 10:01   ` sashiko-bot
2026-07-06 15:42     ` Mahe Tardy
2026-07-06 10:30   ` bot+bpf-ci
2026-07-06 15:28     ` Mahe Tardy
2026-07-06 16:58   ` Stanislav Fomichev
2026-07-06 17:26     ` Mahe Tardy
2026-07-06 20:21       ` Amery Hung
2026-07-06 21:02       ` Stanislav Fomichev
2026-07-06 22:50         ` Kuniyuki Iwashima
2026-07-07  9:41           ` Mahe Tardy
2026-07-06 21:33   ` Amery Hung
2026-07-07  9:48     ` Mahe Tardy
2026-07-06 23:01   ` Kuniyuki Iwashima
2026-07-07 10:06     ` Mahe Tardy [this message]
2026-07-06  9:35 ` [PATCH bpf-next 3/6] selftests/bpf: Add ksock kfunc test Mahe Tardy
2026-07-06 10:10   ` sashiko-bot
2026-07-06 16:11     ` Mahe Tardy
2026-07-06 10:16   ` bot+bpf-ci
2026-07-06 15:27     ` Mahe Tardy
2026-07-06  9:35 ` [PATCH bpf-next 4/6] selftests/bpf: Add ksock LSM recursion test Mahe Tardy
2026-07-06  9:35 ` [PATCH bpf-next 5/6] selftests/bpf: Add ksock net ns quota tests Mahe Tardy
2026-07-06  9:35 ` [PATCH bpf-next 6/6] selftests/bpf: Add ksock test for async callback guard Mahe Tardy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=akzPl9lLtjcRFXxD@gmail.com \
    --to=mahe.tardy@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=eddyz87@gmail.com \
    --cc=edumazet@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=liamwisehart@meta.com \
    --cc=martin.lau@linux.dev \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=song@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.