From: sashiko-bot@kernel.org
To: "Leon Hwang" <leon.hwang@linux.dev>, bpf@vger.kernel.org
Cc: linux-trace-kernel@vger.kernel.org
Subject: Re: [PATCH bpf-next 2/6] bpf: Add syscall common attrs support for xdp link_create
Date: Sat, 17 Oct 2026 14:48:30 +0000 [thread overview]
Message-ID: <sashiko-outbox-175566@kernel.org> (raw)
In-Reply-To: <20261017142649.51047-3-leon.hwang@linux.dev>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] bpf: NULL deref and format string bug in bpf_xdp_link_attach() via bpf_log()
- [Critical] bpf: prog refcount underflow in link_create() if bpf_log_attr_finalize() fails
- [Low] bpf: link failure in bpf_xdp_link_attach() when !CONFIG_BPF_SYSCALL
--
commit fa16fd00d8499a718392032e57d440248e048afc
Author: Leon Hwang <leon.hwang@linux.dev>
bpf: Add syscall common attrs support for xdp link_create
This commit passes the verifier log to bpf_xdp_link_attach() so that XDP
link creation can report target_ifindex and driver errors through BPF
syscall common attributes.
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 252b479937a4d..e96d5f09486f5 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -5921,7 +5921,7 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_common_a
> break;
> #ifdef CONFIG_NET
> case BPF_PROG_TYPE_XDP:
> - ret = bpf_xdp_link_attach(attr, prog);
> + ret = bpf_xdp_link_attach(attr, prog, log);
> break;
> case BPF_PROG_TYPE_SCHED_CLS:
> if (attr->link_create.attach_type == BPF_TCX_INGRESS ||
[Severity: Critical]
Can the cleanup path in link_create() underflow prog's reference count if
bpf_log_attr_finalize() fails after bpf_xdp_link_attach() succeeds?
When bpf_xdp_link_attach() succeeds, bpf_link_init() transfers ownership of
prog's reference to link->link.prog and bpf_link_settle() installs the link
file descriptor, returning a non-negative fd in ret.
At the out label in link_create(), bpf_log_attr_finalize() writes
log_true_size to uattr_common even when nothing was logged:
kernel/bpf/log.c:bpf_log_attr_finalize() {
...
if (attr->offsetof_true_size &&
copy_to_bpfptr_offset(attr->uattr, attr->offsetof_true_size, &log_true_size,
sizeof(log_true_size)))
return -EFAULT;
}
If uattr_common points to read-only memory, copy_from_bpfptr() in
__sys_bpf() succeeds, bpf_xdp_link_attach() attaches and settles the link,
and then bpf_log_attr_finalize() returns -EFAULT:
kernel/bpf/syscall.c:link_create() {
out:
/* preserve original error even if log finalization is successful */
err = bpf_log_attr_finalize(&attr_log, log);
if (err)
ret = err;
kfree(log);
if (ret < 0 && prog)
bpf_prog_put(prog);
return ret;
}
Overwriting ret with err causes link_create() to call bpf_prog_put(prog) on
a reference that is now owned by the settled bpf_link, leading to a
use-after-free of struct bpf_prog while the link remains attached in the
process fd table.
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 18dc88990510a..fdc1de21f3589 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
[ ... ]
> @@ -10771,7 +10772,8 @@ static const struct bpf_link_ops bpf_xdp_link_lops = {
> .update_prog = bpf_xdp_link_update,
> };
>
> -int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
> +int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog,
> + struct bpf_verifier_log *log)
> {
> struct net *net = current->nsproxy->net_ns;
> struct bpf_link_primer link_primer;
> @@ -10784,6 +10786,7 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
> dev = dev_get_by_index(net, attr->link_create.target_ifindex);
> if (!dev) {
> rtnl_unlock();
> + bpf_log(log, "Invalid target_ifindex.\n");
> return -EINVAL;
> }
[Severity: Low]
Will calling bpf_log() in bpf_xdp_link_attach() break linking when
CONFIG_NET=y and CONFIG_BPF_SYSCALL=n?
net/core/dev.c is compiled whenever CONFIG_NET=y, and bpf_xdp_link_attach()
is not guarded by CONFIG_BPF_SYSCALL. While helpers like bpf_link_init() and
bpf_link_prime() have static inline stubs in include/linux/bpf.h when
!CONFIG_BPF_SYSCALL, bpf_log() is only compiled via kernel/bpf/log.o when
CONFIG_BPF_SYSCALL=y and has no stub in include/linux/bpf_verifier.h.
>
> @@ -10812,6 +10815,7 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
> if (err) {
> link->dev = NULL;
> bpf_link_cleanup(&link_primer);
> + bpf_log(log, extack._msg);
> trace_bpf_xdp_link_attach_failed(extack._msg);
> goto out_put_dev;
> }
[Severity: Critical]
What happens here when dev_xdp_attach_link() fails without setting an extack
message, or when extack._msg contains format specifiers?
In bpf_xdp_link_attach(), extack is zero-initialized on the stack, so
extack._msg starts as NULL. Many failure paths under dev_xdp_attach_link() ->
dev_xdp_attach() -> dev_xdp_install() return an error without calling
NL_SET_ERR_MSG(), such as netif_xdp_propagate() when a device has no ndo_bpf
callback, or driver ndo_bpf callbacks like netkit_xdp() and veth_xdp()
returning -EOPNOTSUPP or -EINVAL.
When a user provides a log buffer via syscall common attributes and
extack._msg is NULL, bpf_log() passes fmt = NULL into
bpf_verifier_vlog() -> vscnprintf() -> vsnprintf(), which dereferences fmt
unconditionally and crashes the kernel.
Additionally, because bpf_log() is a printf-style function, passing
extack._msg directly as the format string rather than using a "%s\n" format
specifier allows any '%' characters in a formatted extack message (for
example from NL_SET_ERR_MSG_FMT() containing an interface name) to be
interpreted as format specifiers by vscnprintf(), and omits the trailing
newline. Should this be guarded with if (extack._msg) and logged with
bpf_log(log, "%s\n", extack._msg)?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261017142649.51047-1-leon.hwang@linux.dev?part=2
next prev parent reply other threads:[~2026-10-17 14:48 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 14:26 [PATCH bpf-next 0/6] bpf: Add syscall common attrs support for xdp link_create Leon Hwang
2026-10-17 14:26 ` [PATCH bpf-next 1/6] bpf: Add syscall common attrs support for link_create Leon Hwang
2026-10-17 14:39 ` sashiko-bot
2026-10-17 14:26 ` [PATCH bpf-next 2/6] bpf: Add syscall common attrs support for xdp link_create Leon Hwang
2026-10-17 14:48 ` sashiko-bot [this message]
2026-10-17 15:03 ` bot+bpf-ci
2026-10-18 3:28 ` kernel test robot
2026-10-18 3:46 ` kernel test robot
2026-10-17 14:26 ` [PATCH bpf-next 3/6] bpf: Retire tracepoint bpf_xdp_link_attach_failed Leon Hwang
2026-10-17 14:26 ` [PATCH bpf-next 4/6] libbpf: Factor out __bpf_sys_fd helper Leon Hwang
2026-10-17 14:53 ` bot+bpf-ci
2026-10-17 14:26 ` [PATCH bpf-next 5/6] libbpf: Add bpf_link_create_log API Leon Hwang
2026-10-17 14:43 ` sashiko-bot
2026-10-17 15:03 ` bot+bpf-ci
2026-10-17 14:26 ` [PATCH bpf-next 6/6] selftests/bpf: Add tests to verify link_create logs Leon Hwang
2026-10-17 15:02 ` bot+bpf-ci
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=sashiko-outbox-175566@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=leon.hwang@linux.dev \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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.