The printing functions in BPF code are using printf() type of format, and compiler is not happy about them as is: kernel/bpf/helpers.c:1069:9: error: function ‘____bpf_snprintf’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] 1069 | err = bstr_printf(str, str_size, fmt, data.bin_args); | ^~~ kernel/trace/bpf_trace.c:377:9: error: function ‘____bpf_trace_printk’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] 377 | ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt, data.bin_args); | ^~~ kernel/trace/bpf_trace.c:433:9: error: function ‘____bpf_trace_vprintk’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] 433 | ret = bstr_printf(data.buf, MAX_BPRINTF_BUF, fmt, data.bin_args); | ^~~ kernel/trace/bpf_trace.c:475:9: error: function ‘____bpf_seq_printf’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] 475 | seq_bprintf(m, fmt, data.bin_args); | ^~~~~~~~~~~ Fix the compilation errors by adding __printf() attribute. For that we need to pass it down to the BPF_CALL_x() and wrap into PRINTF_BPF_CALL_*() to make code neater. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202512061425.x0qTt9ww-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202512061640.9hKTnB8p-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202512081321.2h9ThWTg-lkp@intel.com/ Fixes: 10aceb629e19 ("bpf: Add bpf_trace_vprintk helper") Fixes: 7b15523a989b ("bpf: Add a bpf_snprintf helper") Fixes: 492e639f0c22 ("bpf: Add bpf_seq_printf and bpf_seq_write helpers") Fixes: f3694e001238 ("bpf: add BPF_CALL_x macros for declaring helpers") Signed-off-by: Andy Shevchenko --- This is combined change and I think there is no need to split it, but if required I can do it in a four changes. Note, the culprits are older than 4 years and stable kernels anyway don't go that deep nowadays. include/linux/filter.h | 24 +++++++++++++++--------- kernel/bpf/helpers.c | 2 +- kernel/trace/bpf_trace.c | 6 +++--- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index fd54fed8f95f..31034a74af22 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -607,9 +607,9 @@ static inline bool insn_is_cast_user(const struct bpf_insn *insn) __BPF_MAP(n, __BPF_DECL_ARGS, __BPF_N, u64, __ur_1, u64, __ur_2, \ u64, __ur_3, u64, __ur_4, u64, __ur_5) -#define BPF_CALL_x(x, attr, name, ...) \ +#define BPF_CALL_x(x, __attr, attr, name, ...) \ static __always_inline \ - u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \ + __attr u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \ typedef u64 (*btf_##name)(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \ attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \ attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \ @@ -620,14 +620,20 @@ static inline bool insn_is_cast_user(const struct bpf_insn *insn) u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)) #define __NOATTR -#define BPF_CALL_0(name, ...) BPF_CALL_x(0, __NOATTR, name, __VA_ARGS__) -#define BPF_CALL_1(name, ...) BPF_CALL_x(1, __NOATTR, name, __VA_ARGS__) -#define BPF_CALL_2(name, ...) BPF_CALL_x(2, __NOATTR, name, __VA_ARGS__) -#define BPF_CALL_3(name, ...) BPF_CALL_x(3, __NOATTR, name, __VA_ARGS__) -#define BPF_CALL_4(name, ...) BPF_CALL_x(4, __NOATTR, name, __VA_ARGS__) -#define BPF_CALL_5(name, ...) BPF_CALL_x(5, __NOATTR, name, __VA_ARGS__) +#define BPF_CALL_0(name, ...) BPF_CALL_x(0, __NOATTR, __NOATTR, name, __VA_ARGS__) +#define BPF_CALL_1(name, ...) BPF_CALL_x(1, __NOATTR, __NOATTR, name, __VA_ARGS__) +#define BPF_CALL_2(name, ...) BPF_CALL_x(2, __NOATTR, __NOATTR, name, __VA_ARGS__) +#define BPF_CALL_3(name, ...) BPF_CALL_x(3, __NOATTR, __NOATTR, name, __VA_ARGS__) +#define BPF_CALL_4(name, ...) BPF_CALL_x(4, __NOATTR, __NOATTR, name, __VA_ARGS__) +#define BPF_CALL_5(name, ...) BPF_CALL_x(5, __NOATTR, __NOATTR, name, __VA_ARGS__) -#define NOTRACE_BPF_CALL_1(name, ...) BPF_CALL_x(1, notrace, name, __VA_ARGS__) +#define PRINTF_BPF_CALL_x(p, name, x, ...) \ + BPF_CALL_x(x, __printf(p, 0), __NOATTR, name, __VA_ARGS__) + +#define PRINTF_BPF_CALL_4(p, name, ...) PRINTF_BPF_CALL_x(p, name, 4, __VA_ARGS__) +#define PRINTF_BPF_CALL_5(p, name, ...) PRINTF_BPF_CALL_x(p, name, 5, __VA_ARGS__) + +#define NOTRACE_BPF_CALL_1(name, ...) BPF_CALL_x(1, __NOATTR, notrace, name, __VA_ARGS__) #define bpf_ctx_range(TYPE, MEMBER) \ offsetof(TYPE, MEMBER) ... offsetofend(TYPE, MEMBER) - 1 diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index db72b96f9c8c..cbc66865e3dc 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1046,7 +1046,7 @@ int bpf_bprintf_prepare(const char *fmt, u32 fmt_size, const u64 *raw_args, return err; } -BPF_CALL_5(bpf_snprintf, char *, str, u32, str_size, char *, fmt, +PRINTF_BPF_CALL_5(3, bpf_snprintf, char *, str, u32, str_size, char *, fmt, const void *, args, u32, data_len) { struct bpf_bprintf_data data = { diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index d57727abaade..5fd46b4bcf48 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -359,7 +359,7 @@ static const struct bpf_func_proto bpf_probe_write_user_proto = { #define MAX_TRACE_PRINTK_VARARGS 3 #define BPF_TRACE_PRINTK_SIZE 1024 -BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, +PRINTF_BPF_CALL_5(1, bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, u64, arg2, u64, arg3) { u64 args[MAX_TRACE_PRINTK_VARARGS] = { arg1, arg2, arg3 }; @@ -412,7 +412,7 @@ const struct bpf_func_proto *bpf_get_trace_printk_proto(void) return &bpf_trace_printk_proto; } -BPF_CALL_4(bpf_trace_vprintk, char *, fmt, u32, fmt_size, const void *, args, +PRINTF_BPF_CALL_4(1, bpf_trace_vprintk, char *, fmt, u32, fmt_size, const void *, args, u32, data_len) { struct bpf_bprintf_data data = { @@ -455,7 +455,7 @@ const struct bpf_func_proto *bpf_get_trace_vprintk_proto(void) return &bpf_trace_vprintk_proto; } -BPF_CALL_5(bpf_seq_printf, struct seq_file *, m, char *, fmt, u32, fmt_size, +PRINTF_BPF_CALL_5(2, bpf_seq_printf, struct seq_file *, m, char *, fmt, u32, fmt_size, const void *, args, u32, data_len) { struct bpf_bprintf_data data = { -- 2.50.1