BPF_BTF_LOAD can now provide log parameters through both union bpf_attr and bpf_common_attr. Apply the same conflict and precedence rules as prog_load:
- if both are provided and btf_log_buf/btf_log_size/btf_log_level match, use them; - if only one side provides a log buffer, use that one; - if both provide log buffers but differ, return -EINVAL. Signed-off-by: Leon Hwang <[email protected]> --- include/linux/bpf_verifier.h | 3 ++- kernel/bpf/log.c | 18 ++++++++++++++++-- kernel/bpf/syscall.c | 3 ++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index b6e33ee82f63..1144657bbc2f 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -641,7 +641,8 @@ int bpf_prog_load_log_attr_init(struct bpf_log_attr *attr_log, union bpf_attr *a bpfptr_t uattr, u32 size, struct bpf_common_attr *attr_common, bpfptr_t uattr_common, u32 size_common); int bpf_btf_load_log_attr_init(struct bpf_log_attr *attr_log, union bpf_attr *attr, - bpfptr_t uattr, u32 size); + bpfptr_t uattr, u32 size, struct bpf_common_attr *attr_common, + bpfptr_t uattr_common, u32 size_common); int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_log *log); #define BPF_MAX_SUBPROGS 256 diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index 8ad88e4aa12c..db2716586f85 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -901,9 +901,23 @@ int bpf_prog_load_log_attr_init(struct bpf_log_attr *attr_log, union bpf_attr *a } int bpf_btf_load_log_attr_init(struct bpf_log_attr *attr_log, union bpf_attr *attr, - bpfptr_t uattr, u32 size) + bpfptr_t uattr, u32 size, struct bpf_common_attr *attr_common, + bpfptr_t uattr_common, u32 size_common) { - bpf_log_attr_init(attr_log, offsetof(union bpf_attr, btf_log_true_size), uattr, size); + if (bpf_log_attrs_diff(attr_common, attr->btf_log_buf, attr->btf_log_size, + attr->btf_log_level)) + return -EINVAL; + + if (!attr->btf_log_buf && attr_common->log_buf) { + attr->btf_log_buf = attr_common->log_buf; + attr->btf_log_size = attr_common->log_size; + attr->btf_log_level = attr_common->log_level; + bpf_log_attr_init(attr_log, offsetof(struct bpf_common_attr, log_true_size), + uattr_common, size_common); + } else { + bpf_log_attr_init(attr_log, offsetof(union bpf_attr, btf_log_true_size), uattr, + size); + } return 0; } diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index b6e4ec641dc1..4a8933c1dd38 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -6279,7 +6279,8 @@ 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_log_attr_init(&attr_log, &attr, uattr, size); + err = bpf_btf_load_log_attr_init(&attr_log, &attr, uattr, size, &attr_common, + uattr_common, size_common); err = err ?: bpf_btf_load(&attr, uattr, &attr_log); break; case BPF_BTF_GET_FD_BY_ID: -- 2.52.0

