From: Leon Hwang <leon.hwang@linux.dev>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net,
menglong8.dong@gmail.com, Leon Hwang <leon.hwang@linux.dev>
Subject: [RFC PATCH bpf-next v2 3/6] bpf: Add common attr support for prog_load and btf_load
Date: Fri, 12 Sep 2025 00:33:25 +0800 [thread overview]
Message-ID: <20250911163328.93490-4-leon.hwang@linux.dev> (raw)
In-Reply-To: <20250911163328.93490-1-leon.hwang@linux.dev>
The log buffer of common attributes would be confusing with the one in
'union bpf_attr' for BPF_PROG_LOAD and BPF_BTF_LOAD.
In order to clarify the usage of these two 'log_buf's, they both can be
used for logging if:
* They are same, including 'log_buf', 'log_level' and 'log_size'.
* One of them is missing, then another one will be used for logging.
If they both have 'log_buf' but they are not same, a log message will be
written to the log buffer of 'union bpf_attr'.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/bpf.h | 3 ++-
include/linux/bpf_verifier.h | 2 +-
include/linux/btf.h | 3 ++-
kernel/bpf/btf.c | 12 +++++++-----
kernel/bpf/log.c | 23 ++++++++++++++++++++++-
kernel/bpf/syscall.c | 14 ++++++++------
kernel/bpf/verifier.c | 8 ++++----
7 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 8f6e87f0f3a89..adc0e68cb4e50 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2717,7 +2717,8 @@ int bpf_check_uarg_tail_zero(bpfptr_t uaddr, size_t expected_size,
size_t actual_size);
/* verify correctness of eBPF program */
-int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size);
+int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ struct bpf_common_attr *common_attrs);
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth);
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 020de62bd09cd..2d61afec91c92 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -864,7 +864,7 @@ __printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
__printf(2, 3) void bpf_log(struct bpf_verifier_log *log,
const char *fmt, ...);
int bpf_vlog_init(struct bpf_verifier_log *log, u32 log_level,
- char __user *log_buf, u32 log_size);
+ char __user *log_buf, u32 log_size, const struct bpf_common_attr *common_attrs);
void bpf_vlog_reset(struct bpf_verifier_log *log, u64 new_pos);
int bpf_vlog_finalize(struct bpf_verifier_log *log, u32 *log_size_actual);
diff --git a/include/linux/btf.h b/include/linux/btf.h
index 9eda6b113f9b4..c0acb46930bde 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -145,7 +145,8 @@ const char *btf_get_name(const struct btf *btf);
void btf_get(struct btf *btf);
void btf_put(struct btf *btf);
const struct btf_header *btf_header(const struct btf *btf);
-int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz);
+int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz,
+ const struct bpf_common_attr *common_attrs);
struct btf *btf_get_by_fd(int fd);
int btf_get_info_by_fd(const struct btf *btf,
const union bpf_attr *attr,
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 64739308902f7..4a17ae4842210 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -5771,7 +5771,8 @@ static int finalize_log(struct bpf_verifier_log *log, bpfptr_t uattr, u32 uattr_
return err;
}
-static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ const struct bpf_common_attr *common_attrs)
{
bpfptr_t btf_data = make_bpfptr(attr->btf, uattr.is_kernel);
char __user *log_ubuf = u64_to_user_ptr(attr->btf_log_buf);
@@ -5791,8 +5792,8 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
/* user could have requested verbose verifier output
* and supplied buffer to store the verification trace
*/
- err = bpf_vlog_init(&env->log, attr->btf_log_level,
- log_ubuf, attr->btf_log_size);
+ err = bpf_vlog_init(&env->log, attr->btf_log_level, log_ubuf, attr->btf_log_size,
+ common_attrs);
if (err)
goto errout_free;
@@ -8028,12 +8029,13 @@ static int __btf_new_fd(struct btf *btf)
return anon_inode_getfd("btf", &btf_fops, btf, O_RDONLY | O_CLOEXEC);
}
-int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ const struct bpf_common_attr *common_attrs)
{
struct btf *btf;
int ret;
- btf = btf_parse(attr, uattr, uattr_size);
+ btf = btf_parse(attr, uattr, uattr_size, common_attrs);
if (IS_ERR(btf))
return PTR_ERR(btf);
diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
index e4983c1303e76..a9a0834884eb9 100644
--- a/kernel/bpf/log.c
+++ b/kernel/bpf/log.c
@@ -29,12 +29,33 @@ static bool bpf_verifier_log_attr_valid(const struct bpf_verifier_log *log)
}
int bpf_vlog_init(struct bpf_verifier_log *log, u32 log_level,
- char __user *log_buf, u32 log_size)
+ char __user *log_buf, u32 log_size, const struct bpf_common_attr *common_attrs)
{
+ u32 log_true_size;
+ int err;
+
log->level = log_level;
log->ubuf = log_buf;
log->len_total = log_size;
+ if (log_buf && common_attrs && common_attrs->log_buf &&
+ ((u64) log_buf != common_attrs->log_buf || log_level != common_attrs->log_level ||
+ log_size != common_attrs->log_size)) {
+ if (!bpf_verifier_log_attr_valid(log))
+ return -EINVAL;
+ bpf_log(log, "Conflict log configs between bpf_attr and common_attr.\n");
+ err = bpf_vlog_finalize(log, &log_true_size);
+ if (err)
+ return err;
+ return -EINVAL;
+ }
+
+ if (!log_buf && common_attrs && common_attrs->log_buf) {
+ log->level = common_attrs->log_level;
+ log->ubuf = u64_to_user_ptr(common_attrs->log_buf);
+ log->len_total = common_attrs->log_size;
+ }
+
/* log attributes have to be sane */
if (!bpf_verifier_log_attr_valid(log))
return -EINVAL;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index d49f822ceea12..5e5cf0262a14e 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2764,7 +2764,8 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
/* last field in 'union bpf_attr' used by this command */
#define BPF_PROG_LOAD_LAST_FIELD fd_array_cnt
-static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ struct bpf_common_attr *common_attrs)
{
enum bpf_prog_type type = attr->prog_type;
struct bpf_prog *prog, *dst_prog = NULL;
@@ -2976,7 +2977,7 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
goto free_prog_sec;
/* run eBPF verifier */
- err = bpf_check(&prog, attr, uattr, uattr_size);
+ err = bpf_check(&prog, attr, uattr, uattr_size, common_attrs);
if (err < 0)
goto free_used_maps;
@@ -5292,7 +5293,8 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
#define BPF_BTF_LOAD_LAST_FIELD btf_token_fd
-static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
+static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size,
+ struct bpf_common_attr *common_attrs)
{
struct bpf_token *token = NULL;
@@ -5319,7 +5321,7 @@ static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_
bpf_token_put(token);
- return btf_new_fd(attr, uattr, uattr_size);
+ return btf_new_fd(attr, uattr, uattr_size, common_attrs);
}
#define BPF_BTF_GET_FD_BY_ID_LAST_FIELD fd_by_id_token_fd
@@ -6036,7 +6038,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
err = map_freeze(&attr);
break;
case BPF_PROG_LOAD:
- err = bpf_prog_load(&attr, uattr, size);
+ err = bpf_prog_load(&attr, uattr, size, &common_attrs);
break;
case BPF_OBJ_PIN:
err = bpf_obj_pin(&attr);
@@ -6081,7 +6083,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
err = bpf_raw_tracepoint_open(&attr);
break;
case BPF_BTF_LOAD:
- err = bpf_btf_load(&attr, uattr, size);
+ err = bpf_btf_load(&attr, uattr, size, &common_attrs);
break;
case BPF_BTF_GET_FD_BY_ID:
err = bpf_btf_get_fd_by_id(&attr);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index b9394f8fac0ed..77b57289ec097 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -24584,7 +24584,8 @@ static int compute_scc(struct bpf_verifier_env *env)
return err;
}
-int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
+int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size,
+ struct bpf_common_attr *common_attrs)
{
u64 start_time = ktime_get_ns();
struct bpf_verifier_env *env;
@@ -24633,9 +24634,8 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
/* user could have requested verbose verifier output
* and supplied buffer to store the verification trace
*/
- ret = bpf_vlog_init(&env->log, attr->log_level,
- (char __user *) (unsigned long) attr->log_buf,
- attr->log_size);
+ ret = bpf_vlog_init(&env->log, attr->log_level, u64_to_user_ptr(attr->log_buf),
+ attr->log_size, common_attrs);
if (ret)
goto err_unlock;
--
2.50.1
next prev parent reply other threads:[~2025-09-11 16:33 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-11 16:33 [RFC PATCH bpf-next v2 0/6] bpf: Extend bpf syscall with common attributes support Leon Hwang
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 1/6] " Leon Hwang
2025-09-17 0:06 ` Andrii Nakryiko
2025-09-23 15:23 ` Leon Hwang
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 2/6] libbpf: Add support for extended bpf syscall Leon Hwang
2025-09-17 0:06 ` Andrii Nakryiko
2025-09-23 15:36 ` Leon Hwang
2025-09-24 23:57 ` Andrii Nakryiko
2025-09-11 16:33 ` Leon Hwang [this message]
2025-09-17 21:12 ` [RFC PATCH bpf-next v2 3/6] bpf: Add common attr support for prog_load and btf_load Andrii Nakryiko
2025-09-23 15:50 ` Leon Hwang
2025-09-25 0:00 ` Andrii Nakryiko
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 4/6] bpf: Add common attr support for map_create Leon Hwang
2025-09-17 21:39 ` Andrii Nakryiko
2025-09-17 21:49 ` Alexei Starovoitov
2025-09-23 15:52 ` Leon Hwang
2025-09-23 16:27 ` Leon Hwang
2025-09-18 23:29 ` Eduard Zingerman
2025-09-23 16:31 ` Leon Hwang
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 5/6] libbpf: " Leon Hwang
2025-09-17 21:45 ` Andrii Nakryiko
2025-09-17 21:46 ` Andrii Nakryiko
2025-09-23 16:40 ` Leon Hwang
2025-09-25 0:02 ` Andrii Nakryiko
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 6/6] selftests/bpf: Add cases to test map create failure log Leon Hwang
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=20250911163328.93490-4-leon.hwang@linux.dev \
--to=leon.hwang@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=menglong8.dong@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox