diff mbox series

[bpf-next,v5,1/3] bpf: Prevent tailcall infinite loop caused by freplace

Message ID 20241006130130.77125-2-leon.hwang@linux.dev (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf: Fix tailcall infinite loop caused by freplace | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-17 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-15 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-next-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-21 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 206 this patch: 206
netdev/build_tools success Errors and warnings before: 0 (+1) this patch: 0 (+1)
netdev/cc_maintainers warning 7 maintainers not CCed: john.fastabend@gmail.com sdf@fomichev.me martin.lau@linux.dev song@kernel.org haoluo@google.com kpsingh@kernel.org jolsa@kernel.org
netdev/build_clang success Errors and warnings before: 257 this patch: 257
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 6961 this patch: 6961
netdev/checkpatch warning CHECK: Please use a blank line after function/struct/union/enum declarations WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP WARNING: The commit message has 'Call Trace:', perhaps it also needs a 'Fixes:' tag? WARNING: line length of 85 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 6 this patch: 6
netdev/source_inline success Was 0 now: 0

Commit Message

Leon Hwang Oct. 6, 2024, 1:01 p.m. UTC
This patch prevents an infinite loop issue caused by combination of tailcall
and freplace.

For example:

tc_bpf2bpf.c:

// SPDX-License-Identifier: GPL-2.0

\#include <linux/bpf.h>
\#include <bpf/bpf_helpers.h>

__noinline
int subprog_tc(struct __sk_buff *skb)
{
	return skb->len * 2;
}

SEC("tc")
int entry_tc(struct __sk_buff *skb)
{
	return subprog_tc(skb);
}

char __license[] SEC("license") = "GPL";

tailcall_freplace.c:

// SPDX-License-Identifier: GPL-2.0

\#include <linux/bpf.h>
\#include <bpf/bpf_helpers.h>

struct {
	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
	__uint(max_entries, 1);
	__uint(key_size, sizeof(__u32));
	__uint(value_size, sizeof(__u32));
} jmp_table SEC(".maps");

int count = 0;

SEC("freplace")
int entry_freplace(struct __sk_buff *skb)
{
	count++;
	bpf_tail_call_static(skb, &jmp_table, 0);
	return count;
}

char __license[] SEC("license") = "GPL";

The attach target of entry_freplace is subprog_tc, and the tail callee
in entry_freplace is entry_tc.

Then, the infinite loop will be entry_tc -> subprog_tc -> entry_freplace
--tailcall-> entry_tc, because tail_call_cnt in entry_freplace will count
from zero for every time of entry_freplace execution. Kernel will panic,
like:

[   15.310490] BUG: TASK stack guard page was hit at (____ptrval____)
(stack is (____ptrval____)..(____ptrval____))
[   15.310490] Oops: stack guard page: 0000 [#1] PREEMPT SMP NOPTI
[   15.310490] CPU: 1 PID: 89 Comm: test_progs Tainted: G           OE
   6.10.0-rc6-g026dcdae8d3e-dirty #72
[   15.310490] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX,
1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   15.310490] RIP: 0010:bpf_prog_3a140cef239a4b4f_subprog_tail+0x14/0x53
[   15.310490] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
cc cc cc cc cc f3 0f 1e fa 0f 1f 44 00 00 0f 1f 00 55 48 89 e5 f3 0f 1e
fa <50> 50 53 41 55 48 89 fb 49 bd 00 2a 46 82 98 9c ff ff 48 89 df 4c
[   15.310490] RSP: 0018:ffffb500c0aa0000 EFLAGS: 00000202
[   15.310490] RAX: ffffb500c0aa0028 RBX: ffff9c98808b7e00 RCX:
0000000000008cb5
[   15.310490] RDX: 0000000000000000 RSI: ffff9c9882462a00 RDI:
ffff9c98808b7e00
[   15.310490] RBP: ffffb500c0aa0000 R08: 0000000000000000 R09:
0000000000000000
[   15.310490] R10: 0000000000000001 R11: 0000000000000000 R12:
ffffb500c01af000
[   15.310490] R13: ffffb500c01cd000 R14: 0000000000000000 R15:
0000000000000000
[   15.310490] FS:  00007f133b665140(0000) GS:ffff9c98bbd00000(0000)
knlGS:0000000000000000
[   15.310490] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   15.310490] CR2: ffffb500c0a9fff8 CR3: 0000000102478000 CR4:
00000000000006f0
[   15.310490] Call Trace:
[   15.310490]  <#DF>
[   15.310490]  ? die+0x36/0x90
[   15.310490]  ? handle_stack_overflow+0x4d/0x60
[   15.310490]  ? exc_double_fault+0x117/0x1a0
[   15.310490]  ? asm_exc_double_fault+0x23/0x30
[   15.310490]  ? bpf_prog_3a140cef239a4b4f_subprog_tail+0x14/0x53
[   15.310490]  </#DF>
[   15.310490]  <TASK>
[   15.310490]  bpf_prog_85781a698094722f_entry+0x4c/0x64
[   15.310490]  bpf_prog_1c515f389a9059b4_entry2+0x19/0x1b
[   15.310490]  ...
[   15.310490]  bpf_prog_85781a698094722f_entry+0x4c/0x64
[   15.310490]  bpf_prog_1c515f389a9059b4_entry2+0x19/0x1b
[   15.310490]  bpf_test_run+0x210/0x370
[   15.310490]  ? bpf_test_run+0x128/0x370
[   15.310490]  bpf_prog_test_run_skb+0x388/0x7a0
[   15.310490]  __sys_bpf+0xdbf/0x2c40
[   15.310490]  ? clockevents_program_event+0x52/0xf0
[   15.310490]  ? lock_release+0xbf/0x290
[   15.310490]  __x64_sys_bpf+0x1e/0x30
[   15.310490]  do_syscall_64+0x68/0x140
[   15.310490]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[   15.310490] RIP: 0033:0x7f133b52725d
[   15.310490] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa
48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f
05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 8b bb 0d 00 f7 d8 64 89 01 48
[   15.310490] RSP: 002b:00007ffddbc10258 EFLAGS: 00000206 ORIG_RAX:
0000000000000141
[   15.310490] RAX: ffffffffffffffda RBX: 00007ffddbc10828 RCX:
00007f133b52725d
[   15.310490] RDX: 0000000000000050 RSI: 00007ffddbc102a0 RDI:
000000000000000a
[   15.310490] RBP: 00007ffddbc10270 R08: 0000000000000000 R09:
00007ffddbc102a0
[   15.310490] R10: 0000000000000064 R11: 0000000000000206 R12:
0000000000000004
[   15.310490] R13: 0000000000000000 R14: 0000558ec4c24890 R15:
00007f133b6ed000
[   15.310490]  </TASK>
[   15.310490] Modules linked in: bpf_testmod(OE)
[   15.310490] ---[ end trace 0000000000000000 ]---
[   15.310490] RIP: 0010:bpf_prog_3a140cef239a4b4f_subprog_tail+0x14/0x53
[   15.310490] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
cc cc cc cc cc f3 0f 1e fa 0f 1f 44 00 00 0f 1f 00 55 48 89 e5 f3 0f 1e
fa <50> 50 53 41 55 48 89 fb 49 bd 00 2a 46 82 98 9c ff ff 48 89 df 4c
[   15.310490] RSP: 0018:ffffb500c0aa0000 EFLAGS: 00000202
[   15.310490] RAX: ffffb500c0aa0028 RBX: ffff9c98808b7e00 RCX:
0000000000008cb5
[   15.310490] RDX: 0000000000000000 RSI: ffff9c9882462a00 RDI:
ffff9c98808b7e00
[   15.310490] RBP: ffffb500c0aa0000 R08: 0000000000000000 R09:
0000000000000000
[   15.310490] R10: 0000000000000001 R11: 0000000000000000 R12:
ffffb500c01af000
[   15.310490] R13: ffffb500c01cd000 R14: 0000000000000000 R15:
0000000000000000
[   15.310490] FS:  00007f133b665140(0000) GS:ffff9c98bbd00000(0000)
knlGS:0000000000000000
[   15.310490] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   15.310490] CR2: ffffb500c0a9fff8 CR3: 0000000102478000 CR4:
00000000000006f0
[   15.310490] Kernel panic - not syncing: Fatal exception in interrupt
[   15.310490] Kernel Offset: 0x30000000 from 0xffffffff81000000
(relocation range: 0xffffffff80000000-0xffffffffbfffffff)

This patch prevents this panic by preventing updating extended prog to
prog_array map and preventing extending a prog, which has been updated
to prog_array map, with freplace prog.

If a prog or its subprog has been extended by freplace prog, the prog
can not be updated to prog_array map.

If a prog has been updated to prog_array map, it or its subprog can not
be extended by freplace prog.

BTW, fix a minor code style issue by replacing 8 spaces with a tab.

Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
 include/linux/bpf.h     | 21 ++++++++++++++++++++
 kernel/bpf/arraymap.c   | 23 +++++++++++++++++++++-
 kernel/bpf/core.c       |  1 +
 kernel/bpf/syscall.c    | 21 ++++++++++++++------
 kernel/bpf/trampoline.c | 43 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 102 insertions(+), 7 deletions(-)

Comments

kernel test robot Oct. 7, 2024, 8:32 p.m. UTC | #1
Hi Leon,

kernel test robot noticed the following build warnings:

[auto build test WARNING on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Leon-Hwang/bpf-Prevent-tailcall-infinite-loop-caused-by-freplace/20241006-210309
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20241006130130.77125-2-leon.hwang%40linux.dev
patch subject: [PATCH bpf-next v5 1/3] bpf: Prevent tailcall infinite loop caused by freplace
config: x86_64-allnoconfig (https://download.01.org/0day-ci/archive/20241008/202410080455.vy5GT8Vz-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241008/202410080455.vy5GT8Vz-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410080455.vy5GT8Vz-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from kernel/fork.c:53:
   In file included from include/linux/security.h:35:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for function 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1392:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         | ^
         | static 
>> include/linux/bpf.h:1398:5: warning: no previous prototype for function 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1398:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         | ^
         | static 
   2 warnings generated.
--
   In file included from kernel/cpu.c:41:
   In file included from include/trace/events/power.h:12:
   In file included from include/linux/trace_events.h:10:
   In file included from include/linux/perf_event.h:62:
   In file included from include/linux/security.h:35:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for function 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1392:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         | ^
         | static 
>> include/linux/bpf.h:1398:5: warning: no previous prototype for function 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1398:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         | ^
         | static 
   kernel/cpu.c:112:20: warning: unused function 'cpuhp_lock_acquire' [-Wunused-function]
     112 | static inline void cpuhp_lock_acquire(bool bringup) { }
         |                    ^~~~~~~~~~~~~~~~~~
   kernel/cpu.c:113:20: warning: unused function 'cpuhp_lock_release' [-Wunused-function]
     113 | static inline void cpuhp_lock_release(bool bringup) { }
         |                    ^~~~~~~~~~~~~~~~~~
   4 warnings generated.
--
   In file included from kernel/sched/core.c:14:
   In file included from include/linux/syscalls_api.h:1:
   In file included from include/linux/syscalls.h:93:
   In file included from include/trace/syscall.h:7:
   In file included from include/linux/trace_events.h:10:
   In file included from include/linux/perf_event.h:62:
   In file included from include/linux/security.h:35:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for function 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1392:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         | ^
         | static 
>> include/linux/bpf.h:1398:5: warning: no previous prototype for function 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1398:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         | ^
         | static 
   kernel/sched/core.c:3595:20: warning: unused function 'rq_has_pinned_tasks' [-Wunused-function]
    3595 | static inline bool rq_has_pinned_tasks(struct rq *rq)
         |                    ^~~~~~~~~~~~~~~~~~~
   kernel/sched/core.c:5751:20: warning: unused function 'sched_tick_start' [-Wunused-function]
    5751 | static inline void sched_tick_start(int cpu) { }
         |                    ^~~~~~~~~~~~~~~~
   kernel/sched/core.c:5752:20: warning: unused function 'sched_tick_stop' [-Wunused-function]
    5752 | static inline void sched_tick_stop(int cpu) { }
         |                    ^~~~~~~~~~~~~~~
   kernel/sched/core.c:6470:20: warning: unused function 'sched_core_cpu_starting' [-Wunused-function]
    6470 | static inline void sched_core_cpu_starting(unsigned int cpu) {}
         |                    ^~~~~~~~~~~~~~~~~~~~~~~
   kernel/sched/core.c:6471:20: warning: unused function 'sched_core_cpu_deactivate' [-Wunused-function]
    6471 | static inline void sched_core_cpu_deactivate(unsigned int cpu) {}
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/sched/core.c:6472:20: warning: unused function 'sched_core_cpu_dying' [-Wunused-function]
    6472 | static inline void sched_core_cpu_dying(unsigned int cpu) {}
         |                    ^~~~~~~~~~~~~~~~~~~~
   8 warnings generated.
--
   In file included from kernel/sched/fair.c:54:
   In file included from kernel/sched/sched.h:61:
   In file included from include/linux/syscalls_api.h:1:
   In file included from include/linux/syscalls.h:93:
   In file included from include/trace/syscall.h:7:
   In file included from include/linux/trace_events.h:10:
   In file included from include/linux/perf_event.h:62:
   In file included from include/linux/security.h:35:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for function 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1392:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         | ^
         | static 
>> include/linux/bpf.h:1398:5: warning: no previous prototype for function 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1398:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         | ^
         | static 
   kernel/sched/fair.c:481:20: warning: unused function 'list_del_leaf_cfs_rq' [-Wunused-function]
     481 | static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
         |                    ^~~~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:502:19: warning: unused function 'tg_is_idle' [-Wunused-function]
     502 | static inline int tg_is_idle(struct task_group *tg)
         |                   ^~~~~~~~~~
   kernel/sched/fair.c:526:19: warning: unused function 'max_vruntime' [-Wunused-function]
     526 | static inline u64 max_vruntime(u64 max_vruntime, u64 vruntime)
         |                   ^~~~~~~~~~~~
   kernel/sched/fair.c:1389:20: warning: unused function 'is_core_idle' [-Wunused-function]
    1389 | static inline bool is_core_idle(int cpu)
         |                    ^~~~~~~~~~~~
   kernel/sched/fair.c:3650:20: warning: unused function 'account_numa_enqueue' [-Wunused-function]
    3650 | static inline void account_numa_enqueue(struct rq *rq, struct task_struct *p)
         |                    ^~~~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:3654:20: warning: unused function 'account_numa_dequeue' [-Wunused-function]
    3654 | static inline void account_numa_dequeue(struct rq *rq, struct task_struct *p)
         |                    ^~~~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:3658:20: warning: unused function 'update_scan_period' [-Wunused-function]
    3658 | static inline void update_scan_period(struct task_struct *p, int new_cpu)
         |                    ^~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:5225:20: warning: unused function 'cfs_rq_is_decayed' [-Wunused-function]
    5225 | static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq)
         |                    ^~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:5240:20: warning: unused function 'remove_entity_load_avg' [-Wunused-function]
    5240 | static inline void remove_entity_load_avg(struct sched_entity *se) {}
         |                    ^~~~~~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:6753:20: warning: unused function 'cfs_bandwidth_used' [-Wunused-function]
    6753 | static inline bool cfs_bandwidth_used(void)
         |                    ^~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:6761:20: warning: unused function 'sync_throttle' [-Wunused-function]
    6761 | static inline void sync_throttle(struct task_group *tg, int cpu) {}
         |                    ^~~~~~~~~~~~~
   kernel/sched/fair.c:6774:19: warning: unused function 'throttled_lb_pair' [-Wunused-function]
    6774 | static inline int throttled_lb_pair(struct task_group *tg,
         |                   ^~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:6785:37: warning: unused function 'tg_cfs_bandwidth' [-Wunused-function]
    6785 | static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)
         |                                     ^~~~~~~~~~~~~~~~
   kernel/sched/fair.c:6789:20: warning: unused function 'destroy_cfs_bandwidth' [-Wunused-function]
    6789 | static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {}
         |                    ^~~~~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:6790:20: warning: unused function 'update_runtime_enabled' [-Wunused-function]
    6790 | static inline void update_runtime_enabled(struct rq *rq) {}
         |                    ^~~~~~~~~~~~~~~~~~~~~~
   kernel/sched/fair.c:6791:20: warning: unused function 'unthrottle_offline_cfs_rqs' [-Wunused-function]
    6791 | static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {}
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~
   18 warnings generated.
--
   In file included from kernel/time/hrtimer.c:30:
   In file included from include/linux/syscalls.h:93:
   In file included from include/trace/syscall.h:7:
   In file included from include/linux/trace_events.h:10:
   In file included from include/linux/perf_event.h:62:
   In file included from include/linux/security.h:35:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for function 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1392:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         | ^
         | static 
>> include/linux/bpf.h:1398:5: warning: no previous prototype for function 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1398:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         | ^
         | static 
   kernel/time/hrtimer.c:121:21: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
     121 |         [CLOCK_REALTIME]        = HRTIMER_BASE_REALTIME,
         |                                   ^~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:119:27: note: previous initialization is here
     119 |         [0 ... MAX_CLOCKS - 1]  = HRTIMER_MAX_CLOCK_BASES,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:122:22: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
     122 |         [CLOCK_MONOTONIC]       = HRTIMER_BASE_MONOTONIC,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:119:27: note: previous initialization is here
     119 |         [0 ... MAX_CLOCKS - 1]  = HRTIMER_MAX_CLOCK_BASES,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:123:21: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
     123 |         [CLOCK_BOOTTIME]        = HRTIMER_BASE_BOOTTIME,
         |                                   ^~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:119:27: note: previous initialization is here
     119 |         [0 ... MAX_CLOCKS - 1]  = HRTIMER_MAX_CLOCK_BASES,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:124:17: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
     124 |         [CLOCK_TAI]             = HRTIMER_BASE_TAI,
         |                                   ^~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:119:27: note: previous initialization is here
     119 |         [0 ... MAX_CLOCKS - 1]  = HRTIMER_MAX_CLOCK_BASES,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:278:20: warning: unused function 'is_migration_base' [-Wunused-function]
     278 | static inline bool is_migration_base(struct hrtimer_clock_base *base)
         |                    ^~~~~~~~~~~~~~~~~
   7 warnings generated.
--
   In file included from kernel/events/core.c:34:
   In file included from include/linux/syscalls.h:93:
   In file included from include/trace/syscall.h:7:
   In file included from include/linux/trace_events.h:10:
   In file included from include/linux/perf_event.h:62:
   In file included from include/linux/security.h:35:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for function 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1392:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         | ^
         | static 
>> include/linux/bpf.h:1398:5: warning: no previous prototype for function 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^
   include/linux/bpf.h:1398:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         | ^
         | static 
   kernel/events/core.c:9789:19: warning: unused function 'perf_event_set_bpf_handler' [-Wunused-function]
    9789 | static inline int perf_event_set_bpf_handler(struct perf_event *event,
         |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/events/core.c:9796:20: warning: unused function 'perf_event_free_bpf_handler' [-Wunused-function]
    9796 | static inline void perf_event_free_bpf_handler(struct perf_event *event)
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   4 warnings generated.


vim +/bpf_extension_link_prog +1392 include/linux/bpf.h

  1348	
  1349	#define DEFINE_BPF_DISPATCHER(name)					\
  1350		__BPF_DISPATCHER_SC(name);					\
  1351		noinline __bpfcall unsigned int bpf_dispatcher_##name##_func(	\
  1352			const void *ctx,					\
  1353			const struct bpf_insn *insnsi,				\
  1354			bpf_func_t bpf_func)					\
  1355		{								\
  1356			return __BPF_DISPATCHER_CALL(name);			\
  1357		}								\
  1358		EXPORT_SYMBOL(bpf_dispatcher_##name##_func);			\
  1359		struct bpf_dispatcher bpf_dispatcher_##name =			\
  1360			BPF_DISPATCHER_INIT(bpf_dispatcher_##name);
  1361	
  1362	#define DECLARE_BPF_DISPATCHER(name)					\
  1363		unsigned int bpf_dispatcher_##name##_func(			\
  1364			const void *ctx,					\
  1365			const struct bpf_insn *insnsi,				\
  1366			bpf_func_t bpf_func);					\
  1367		extern struct bpf_dispatcher bpf_dispatcher_##name;
  1368	
  1369	#define BPF_DISPATCHER_FUNC(name) bpf_dispatcher_##name##_func
  1370	#define BPF_DISPATCHER_PTR(name) (&bpf_dispatcher_##name)
  1371	void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
  1372					struct bpf_prog *to);
  1373	/* Called only from JIT-enabled code, so there's no need for stubs. */
  1374	void bpf_image_ksym_add(void *data, unsigned int size, struct bpf_ksym *ksym);
  1375	void bpf_image_ksym_del(struct bpf_ksym *ksym);
  1376	void bpf_ksym_add(struct bpf_ksym *ksym);
  1377	void bpf_ksym_del(struct bpf_ksym *ksym);
  1378	int bpf_jit_charge_modmem(u32 size);
  1379	void bpf_jit_uncharge_modmem(u32 size);
  1380	bool bpf_prog_has_trampoline(const struct bpf_prog *prog);
  1381	#else
  1382	static inline int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
  1383						   struct bpf_trampoline *tr)
  1384	{
  1385		return -ENOTSUPP;
  1386	}
  1387	static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
  1388						     struct bpf_trampoline *tr)
  1389	{
  1390		return -ENOTSUPP;
  1391	}
> 1392	int bpf_extension_link_prog(struct bpf_tramp_link *link,
  1393				    struct bpf_trampoline *tr,
  1394				    struct bpf_prog *tgt_prog)
  1395	{
  1396		return -ENOTSUPP;
  1397	}
> 1398	int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
  1399				      struct bpf_trampoline *tr,
  1400				      struct bpf_prog *tgt_prog)
  1401	{
  1402		return -ENOTSUPP;
  1403	}
  1404	static inline struct bpf_trampoline *bpf_trampoline_get(u64 key,
  1405								struct bpf_attach_target_info *tgt_info)
  1406	{
  1407		return NULL;
  1408	}
  1409	static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {}
  1410	#define DEFINE_BPF_DISPATCHER(name)
  1411	#define DECLARE_BPF_DISPATCHER(name)
  1412	#define BPF_DISPATCHER_FUNC(name) bpf_dispatcher_nop_func
  1413	#define BPF_DISPATCHER_PTR(name) NULL
  1414	static inline void bpf_dispatcher_change_prog(struct bpf_dispatcher *d,
  1415						      struct bpf_prog *from,
  1416						      struct bpf_prog *to) {}
  1417	static inline bool is_bpf_image_address(unsigned long address)
  1418	{
  1419		return false;
  1420	}
  1421	static inline bool bpf_prog_has_trampoline(const struct bpf_prog *prog)
  1422	{
  1423		return false;
  1424	}
  1425	#endif
  1426
kernel test robot Oct. 7, 2024, 9:33 p.m. UTC | #2
Hi Leon,

kernel test robot noticed the following build errors:

[auto build test ERROR on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Leon-Hwang/bpf-Prevent-tailcall-infinite-loop-caused-by-freplace/20241006-210309
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20241006130130.77125-2-leon.hwang%40linux.dev
patch subject: [PATCH bpf-next v5 1/3] bpf: Prevent tailcall infinite loop caused by freplace
config: powerpc64-randconfig-r071-20241008 (https://download.01.org/0day-ci/archive/20241008/202410080522.O8nxCK2v-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241008/202410080522.O8nxCK2v-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410080522.O8nxCK2v-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/security.h:35,
                    from include/linux/perf_event.h:62,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:93,
                    from init/main.c:21:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/bpf.h:1398:5: warning: no previous prototype for 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/security.h:35,
                    from include/linux/perf_event.h:62,
                    from include/linux/trace_events.h:10,
                    from include/trace/trace_events.h:21,
                    from include/trace/define_trace.h:102,
                    from include/trace/events/workqueue.h:132,
                    from kernel/workqueue.c:531:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/bpf.h:1398:5: warning: no previous prototype for 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/workqueue.c: In function '__alloc_workqueue':
   kernel/workqueue.c:5665:9: warning: function '__alloc_workqueue' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
    5665 |         name_len = vsnprintf(wq->name, sizeof(wq->name), fmt, args);
         |         ^~~~~~~~
--
   In file included from include/linux/security.h:35,
                    from include/net/scm.h:9,
                    from include/linux/netlink.h:9,
                    from include/uapi/linux/neighbour.h:6,
                    from include/linux/netdevice.h:44,
                    from include/net/sock.h:46,
                    from include/linux/tcp.h:19,
                    from include/linux/ipv6.h:102,
                    from include/net/addrconf.h:65,
                    from lib/vsprintf.c:41:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/bpf.h:1398:5: warning: no previous prototype for 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   lib/vsprintf.c: In function 'va_format':
   lib/vsprintf.c:1683:9: warning: function 'va_format' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
    1683 |         buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
         |         ^~~
--
   In file included from include/linux/security.h:35,
                    from include/linux/perf_event.h:62,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:93,
                    from kernel/time/hrtimer.c:30:
>> include/linux/bpf.h:1392:5: warning: no previous prototype for 'bpf_extension_link_prog' [-Wmissing-prototypes]
    1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/bpf.h:1398:5: warning: no previous prototype for 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
    1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:121:35: warning: initialized field overwritten [-Woverride-init]
     121 |         [CLOCK_REALTIME]        = HRTIMER_BASE_REALTIME,
         |                                   ^~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:121:35: note: (near initialization for 'hrtimer_clock_to_base_table[0]')
   kernel/time/hrtimer.c:122:35: warning: initialized field overwritten [-Woverride-init]
     122 |         [CLOCK_MONOTONIC]       = HRTIMER_BASE_MONOTONIC,
         |                                   ^~~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:122:35: note: (near initialization for 'hrtimer_clock_to_base_table[1]')
   kernel/time/hrtimer.c:123:35: warning: initialized field overwritten [-Woverride-init]
     123 |         [CLOCK_BOOTTIME]        = HRTIMER_BASE_BOOTTIME,
         |                                   ^~~~~~~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:123:35: note: (near initialization for 'hrtimer_clock_to_base_table[7]')
   kernel/time/hrtimer.c:124:35: warning: initialized field overwritten [-Woverride-init]
     124 |         [CLOCK_TAI]             = HRTIMER_BASE_TAI,
         |                                   ^~~~~~~~~~~~~~~~
   kernel/time/hrtimer.c:124:35: note: (near initialization for 'hrtimer_clock_to_base_table[11]')
--
   powerpc64-linux-ld: drivers/char/tpm/eventlog/tpm1.o: in function `bpf_extension_link_prog':
>> tpm1.c:(.text+0x494): multiple definition of `bpf_extension_link_prog'; drivers/char/tpm/eventlog/common.o:common.c:(.text+0x130): first defined here
   powerpc64-linux-ld: drivers/char/tpm/eventlog/tpm1.o: in function `bpf_extension_unlink_prog':
>> tpm1.c:(.text+0x4a4): multiple definition of `bpf_extension_unlink_prog'; drivers/char/tpm/eventlog/common.o:common.c:(.text+0x140): first defined here
   powerpc64-linux-ld: drivers/char/tpm/eventlog/tpm2.o: in function `bpf_extension_link_prog':
   tpm2.c:(.text+0x3d0): multiple definition of `bpf_extension_link_prog'; drivers/char/tpm/eventlog/common.o:common.c:(.text+0x130): first defined here
   powerpc64-linux-ld: drivers/char/tpm/eventlog/tpm2.o: in function `bpf_extension_unlink_prog':
   tpm2.c:(.text+0x3e0): multiple definition of `bpf_extension_unlink_prog'; drivers/char/tpm/eventlog/common.o:common.c:(.text+0x140): first defined here
--
   powerpc64-linux-ld: drivers/i2c/i2c-core-smbus.o: in function `bpf_extension_link_prog':
>> i2c-core-smbus.c:(.text+0x1d40): multiple definition of `bpf_extension_link_prog'; drivers/i2c/i2c-core-base.o:i2c-core-base.c:(.text+0x3e60): first defined here
   powerpc64-linux-ld: drivers/i2c/i2c-core-smbus.o: in function `bpf_extension_unlink_prog':
>> i2c-core-smbus.c:(.text+0x1d50): multiple definition of `bpf_extension_unlink_prog'; drivers/i2c/i2c-core-base.o:i2c-core-base.c:(.text+0x3e70): first defined here
   powerpc64-linux-ld: drivers/i2c/i2c-core-slave.o: in function `bpf_extension_link_prog':
   i2c-core-slave.c:(.text+0x73c): multiple definition of `bpf_extension_link_prog'; drivers/i2c/i2c-core-base.o:i2c-core-base.c:(.text+0x3e60): first defined here
   powerpc64-linux-ld: drivers/i2c/i2c-core-slave.o: in function `bpf_extension_unlink_prog':
   i2c-core-slave.c:(.text+0x74c): multiple definition of `bpf_extension_unlink_prog'; drivers/i2c/i2c-core-base.o:i2c-core-base.c:(.text+0x3e70): first defined here
--
   powerpc64-linux-ld: drivers/scsi/snic/snic_main.o: in function `bpf_extension_link_prog':
>> snic_main.c:(.text+0x234): multiple definition of `bpf_extension_link_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1d4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_main.o: in function `bpf_extension_unlink_prog':
>> snic_main.c:(.text+0x244): multiple definition of `bpf_extension_unlink_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1e4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_res.o: in function `bpf_extension_link_prog':
   snic_res.c:(.text+0x0): multiple definition of `bpf_extension_link_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1d4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_res.o: in function `bpf_extension_unlink_prog':
   snic_res.c:(.text+0x10): multiple definition of `bpf_extension_unlink_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1e4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_isr.o: in function `bpf_extension_link_prog':
   snic_isr.c:(.text+0x1ec): multiple definition of `bpf_extension_link_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1d4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_isr.o: in function `bpf_extension_unlink_prog':
   snic_isr.c:(.text+0x1fc): multiple definition of `bpf_extension_unlink_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1e4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_ctl.o: in function `bpf_extension_link_prog':
   snic_ctl.c:(.text+0x0): multiple definition of `bpf_extension_link_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1d4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_ctl.o: in function `bpf_extension_unlink_prog':
   snic_ctl.c:(.text+0x10): multiple definition of `bpf_extension_unlink_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1e4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_io.o: in function `bpf_extension_link_prog':
   snic_io.c:(.text+0x310): multiple definition of `bpf_extension_link_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1d4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_io.o: in function `bpf_extension_unlink_prog':
   snic_io.c:(.text+0x320): multiple definition of `bpf_extension_unlink_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1e4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_scsi.o: in function `bpf_extension_link_prog':
   snic_scsi.c:(.text+0x3dfc): multiple definition of `bpf_extension_link_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1d4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_scsi.o: in function `bpf_extension_unlink_prog':
   snic_scsi.c:(.text+0x3e0c): multiple definition of `bpf_extension_unlink_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1e4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_disc.o: in function `bpf_extension_link_prog':
   snic_disc.c:(.text+0xbf8): multiple definition of `bpf_extension_link_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1d4): first defined here
   powerpc64-linux-ld: drivers/scsi/snic/snic_disc.o: in function `bpf_extension_unlink_prog':
   snic_disc.c:(.text+0xc08): multiple definition of `bpf_extension_unlink_prog'; drivers/scsi/snic/snic_attrs.o:snic_attrs.c:(.text+0x1e4): first defined here
--
   powerpc64-linux-ld: fs/ext2/xattr.o: in function `bpf_extension_link_prog':
>> xattr.c:(.text+0xd24): multiple definition of `bpf_extension_link_prog'; fs/ext2/trace.o:trace.c:(.text+0x7c0): first defined here
   powerpc64-linux-ld: fs/ext2/xattr.o: in function `bpf_extension_unlink_prog':
>> xattr.c:(.text+0xd34): multiple definition of `bpf_extension_unlink_prog'; fs/ext2/trace.o:trace.c:(.text+0x7d0): first defined here
   powerpc64-linux-ld: fs/ext2/xattr_security.o: in function `bpf_extension_link_prog':
   xattr_security.c:(.text+0xdc): multiple definition of `bpf_extension_link_prog'; fs/ext2/trace.o:trace.c:(.text+0x7c0): first defined here
   powerpc64-linux-ld: fs/ext2/xattr_security.o: in function `bpf_extension_unlink_prog':
   xattr_security.c:(.text+0xec): multiple definition of `bpf_extension_unlink_prog'; fs/ext2/trace.o:trace.c:(.text+0x7d0): first defined here
--
   powerpc64-linux-ld: drivers/nvdimm/bus.o: in function `bpf_extension_link_prog':
>> bus.c:(.text+0x1384): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/bus.o: in function `bpf_extension_unlink_prog':
>> bus.c:(.text+0x1394): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/dimm_devs.o: in function `bpf_extension_link_prog':
   dimm_devs.c:(.text+0x12c0): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/dimm_devs.o: in function `bpf_extension_unlink_prog':
   dimm_devs.c:(.text+0x12d0): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/dimm.o: in function `bpf_extension_link_prog':
   dimm.c:(.text+0x2d0): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/dimm.o: in function `bpf_extension_unlink_prog':
   dimm.c:(.text+0x2e0): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/region_devs.o: in function `bpf_extension_link_prog':
   region_devs.c:(.text+0x1388): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/region_devs.o: in function `bpf_extension_unlink_prog':
   region_devs.c:(.text+0x1398): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/region.o: in function `bpf_extension_link_prog':
   region.c:(.text+0x3d4): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/region.o: in function `bpf_extension_unlink_prog':
   region.c:(.text+0x3e4): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/namespace_devs.o: in function `bpf_extension_link_prog':
   namespace_devs.c:(.text+0x2efc): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/namespace_devs.o: in function `bpf_extension_unlink_prog':
   namespace_devs.c:(.text+0x2f0c): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/label.o: in function `bpf_extension_link_prog':
   label.c:(.text+0x324): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/label.o: in function `bpf_extension_unlink_prog':
   label.c:(.text+0x334): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/badrange.o: in function `bpf_extension_link_prog':
   badrange.c:(.text+0x674): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/badrange.o: in function `bpf_extension_unlink_prog':
   badrange.c:(.text+0x684): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/claim.o: in function `bpf_extension_link_prog':
   claim.c:(.text+0x380): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/claim.o: in function `bpf_extension_unlink_prog':
   claim.c:(.text+0x390): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/btt_devs.o: in function `bpf_extension_link_prog':
   btt_devs.c:(.text+0xb24): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/btt_devs.o: in function `bpf_extension_unlink_prog':
   btt_devs.c:(.text+0xb34): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
   powerpc64-linux-ld: drivers/nvdimm/security.o: in function `bpf_extension_link_prog':
   security.c:(.text+0x4c0): multiple definition of `bpf_extension_link_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe48): first defined here
   powerpc64-linux-ld: drivers/nvdimm/security.o: in function `bpf_extension_unlink_prog':
   security.c:(.text+0x4d0): multiple definition of `bpf_extension_unlink_prog'; drivers/nvdimm/core.o:core.c:(.text+0xe58): first defined here
--
   powerpc64-linux-ld: drivers/pcmcia/cistpl.o: in function `bpf_extension_link_prog':
>> cistpl.c:(.text+0x1430): multiple definition of `bpf_extension_link_prog'; drivers/pcmcia/pcmcia_resource.o:pcmcia_resource.c:(.text+0xec0): first defined here
   powerpc64-linux-ld: drivers/pcmcia/cistpl.o: in function `bpf_extension_unlink_prog':
>> cistpl.c:(.text+0x1440): multiple definition of `bpf_extension_unlink_prog'; drivers/pcmcia/pcmcia_resource.o:pcmcia_resource.c:(.text+0xed0): first defined here
   powerpc64-linux-ld: drivers/pcmcia/pcmcia_cis.o: in function `bpf_extension_link_prog':
   pcmcia_cis.c:(.text+0x718): multiple definition of `bpf_extension_link_prog'; drivers/pcmcia/pcmcia_resource.o:pcmcia_resource.c:(.text+0xec0): first defined here
   powerpc64-linux-ld: drivers/pcmcia/pcmcia_cis.o: in function `bpf_extension_unlink_prog':
   pcmcia_cis.c:(.text+0x728): multiple definition of `bpf_extension_unlink_prog'; drivers/pcmcia/pcmcia_resource.o:pcmcia_resource.c:(.text+0xed0): first defined here
kernel test robot Oct. 7, 2024, 10:04 p.m. UTC | #3
Hi Leon,

kernel test robot noticed the following build errors:

[auto build test ERROR on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Leon-Hwang/bpf-Prevent-tailcall-infinite-loop-caused-by-freplace/20241006-210309
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20241006130130.77125-2-leon.hwang%40linux.dev
patch subject: [PATCH bpf-next v5 1/3] bpf: Prevent tailcall infinite loop caused by freplace
config: arc-nsimosci_hs_defconfig (https://download.01.org/0day-ci/archive/20241008/202410080554.slh2FEXJ-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241008/202410080554.slh2FEXJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410080554.slh2FEXJ-lkp@intel.com/

All errors (new ones prefixed by >>):

   arc-elf-ld: init/do_mounts.o: in function `bpf_extension_link_prog':
>> do_mounts.c:(.text+0x14): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: init/do_mounts.o: in function `bpf_extension_unlink_prog':
>> do_mounts.c:(.text+0x1c): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: init/do_mounts_initrd.o: in function `bpf_extension_link_prog':
   do_mounts_initrd.c:(.text+0x0): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: init/do_mounts_initrd.o: in function `bpf_extension_unlink_prog':
   do_mounts_initrd.c:(.text+0x8): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: init/initramfs.o: in function `bpf_extension_link_prog':
   initramfs.c:(.text+0x44): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: init/initramfs.o: in function `bpf_extension_unlink_prog':
   initramfs.c:(.text+0x4c): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: arch/arc/kernel/ptrace.o: in function `bpf_extension_link_prog':
   ptrace.c:(.text+0x13f4): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: arch/arc/kernel/ptrace.o: in function `bpf_extension_unlink_prog':
   ptrace.c:(.text+0x13fc): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: arch/arc/kernel/process.o: in function `bpf_extension_link_prog':
   process.c:(.text+0x174): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: arch/arc/kernel/process.o: in function `bpf_extension_unlink_prog':
   process.c:(.text+0x17c): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: arch/arc/kernel/signal.o: in function `bpf_extension_link_prog':
   signal.c:(.text+0x45c): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: arch/arc/kernel/signal.o: in function `bpf_extension_unlink_prog':
   signal.c:(.text+0x464): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: arch/arc/kernel/sys.o: in function `bpf_extension_link_prog':
   sys.c:(.text+0x0): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: arch/arc/kernel/sys.o: in function `bpf_extension_unlink_prog':
   sys.c:(.text+0x8): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: arch/arc/kernel/perf_event.o: in function `bpf_extension_link_prog':
   perf_event.c:(.text+0xbb4): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: arch/arc/kernel/perf_event.o: in function `bpf_extension_unlink_prog':
   perf_event.c:(.text+0xbbc): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: arch/arc/mm/fault.o: in function `bpf_extension_link_prog':
   fault.c:(.text+0x28): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: arch/arc/mm/fault.o: in function `bpf_extension_unlink_prog':
   fault.c:(.text+0x30): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: arch/arc/mm/cache.o: in function `bpf_extension_link_prog':
   cache.c:(.text+0x2f4): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: arch/arc/mm/cache.o: in function `bpf_extension_unlink_prog':
   cache.c:(.text+0x2fc): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/fork.o: in function `bpf_extension_link_prog':
   fork.c:(.text+0x1090): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/fork.o: in function `bpf_extension_unlink_prog':
   fork.c:(.text+0x1098): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/exec_domain.o: in function `bpf_extension_link_prog':
   exec_domain.c:(.text+0x14): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/exec_domain.o: in function `bpf_extension_unlink_prog':
   exec_domain.c:(.text+0x1c): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/cpu.o: in function `bpf_extension_link_prog':
   cpu.c:(.text+0xbec): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/cpu.o: in function `bpf_extension_unlink_prog':
   cpu.c:(.text+0xbf4): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/exit.o: in function `bpf_extension_link_prog':
   exit.c:(.text+0x6b4): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/exit.o: in function `bpf_extension_unlink_prog':
   exit.c:(.text+0x6bc): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/softirq.o: in function `bpf_extension_link_prog':
   softirq.c:(.text+0xe88): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/softirq.o: in function `bpf_extension_unlink_prog':
   softirq.c:(.text+0xe90): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/resource.o: in function `bpf_extension_link_prog':
   resource.c:(.text+0xb68): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/resource.o: in function `bpf_extension_unlink_prog':
   resource.c:(.text+0xb70): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/sysctl.o: in function `bpf_extension_link_prog':
   sysctl.c:(.text+0x14f4): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/sysctl.o: in function `bpf_extension_unlink_prog':
   sysctl.c:(.text+0x14fc): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/capability.o: in function `bpf_extension_link_prog':
   capability.c:(.text+0x718): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/capability.o: in function `bpf_extension_unlink_prog':
   capability.c:(.text+0x720): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/ptrace.o: in function `bpf_extension_link_prog':
   ptrace.c:(.text+0x580): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/ptrace.o: in function `bpf_extension_unlink_prog':
   ptrace.c:(.text+0x588): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/signal.o: in function `bpf_extension_link_prog':
   signal.c:(.text+0x1118): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/signal.o: in function `bpf_extension_unlink_prog':
   signal.c:(.text+0x1120): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/sys.o: in function `bpf_extension_link_prog':
   sys.c:(.text+0xf70): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/sys.o: in function `bpf_extension_unlink_prog':
   sys.c:(.text+0xf78): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/umh.o: in function `bpf_extension_link_prog':
   umh.c:(.text+0x5c0): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/umh.o: in function `bpf_extension_unlink_prog':
   umh.c:(.text+0x5c8): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/workqueue.o: in function `bpf_extension_link_prog':
   workqueue.c:(.text+0x55a8): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/workqueue.o: in function `bpf_extension_unlink_prog':
   workqueue.c:(.text+0x55b0): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/pid.o: in function `bpf_extension_link_prog':
   pid.c:(.text+0x308): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/pid.o: in function `bpf_extension_unlink_prog':
   pid.c:(.text+0x310): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/extable.o: in function `bpf_extension_link_prog':
   extable.c:(.text+0x0): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/extable.o: in function `bpf_extension_unlink_prog':
   extable.c:(.text+0x8): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
   arc-elf-ld: kernel/params.o: in function `bpf_extension_link_prog':
   params.c:(.text+0x918): multiple definition of `bpf_extension_link_prog'; init/main.o:main.c:(.text+0x5dc): first defined here
   arc-elf-ld: kernel/params.o: in function `bpf_extension_unlink_prog':
   params.c:(.text+0x920): multiple definition of `bpf_extension_unlink_prog'; init/main.o:main.c:(.text+0x5e4): first defined here
Leon Hwang Oct. 8, 2024, 1:40 a.m. UTC | #4
On 8/10/24 04:32, kernel test robot wrote:
> Hi Leon,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on bpf-next/master]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Leon-Hwang/bpf-Prevent-tailcall-infinite-loop-caused-by-freplace/20241006-210309
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
> patch link:    https://lore.kernel.org/r/20241006130130.77125-2-leon.hwang%40linux.dev
> patch subject: [PATCH bpf-next v5 1/3] bpf: Prevent tailcall infinite loop caused by freplace
> config: x86_64-allnoconfig (https://download.01.org/0day-ci/archive/20241008/202410080455.vy5GT8Vz-lkp@intel.com/config)
> compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241008/202410080455.vy5GT8Vz-lkp@intel.com/reproduce)
> 
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202410080455.vy5GT8Vz-lkp@intel.com/
> 
> All warnings (new ones prefixed by >>):
> 
>    In file included from kernel/fork.c:53:
>    In file included from include/linux/security.h:35:
>>> include/linux/bpf.h:1392:5: warning: no previous prototype for function 'bpf_extension_link_prog' [-Wmissing-prototypes]
>     1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
>          |     ^
>    include/linux/bpf.h:1392:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
>     1392 | int bpf_extension_link_prog(struct bpf_tramp_link *link,
>          | ^
>          | static 
>>> include/linux/bpf.h:1398:5: warning: no previous prototype for function 'bpf_extension_unlink_prog' [-Wmissing-prototypes]
>     1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
>          |     ^
>    include/linux/bpf.h:1398:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
>     1398 | int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
>          | ^
>          | static 
>    2 warnings generated.

Ack.

I'll add 'static' in patch v6.

Thanks,
Leon

[...]
diff mbox series

Patch

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 19d8ca8ac960f..73ee6e77a8ca7 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1294,6 +1294,12 @@  bool __bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr);
 #ifdef CONFIG_BPF_JIT
 int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr);
 int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr);
+int bpf_extension_link_prog(struct bpf_tramp_link *link,
+			    struct bpf_trampoline *tr,
+			    struct bpf_prog *tgt_prog);
+int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
+			      struct bpf_trampoline *tr,
+			      struct bpf_prog *tgt_prog);
 struct bpf_trampoline *bpf_trampoline_get(u64 key,
 					  struct bpf_attach_target_info *tgt_info);
 void bpf_trampoline_put(struct bpf_trampoline *tr);
@@ -1383,6 +1389,18 @@  static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
 {
 	return -ENOTSUPP;
 }
+int bpf_extension_link_prog(struct bpf_tramp_link *link,
+			    struct bpf_trampoline *tr,
+			    struct bpf_prog *tgt_prog)
+{
+	return -ENOTSUPP;
+}
+int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
+			      struct bpf_trampoline *tr,
+			      struct bpf_prog *tgt_prog)
+{
+	return -ENOTSUPP;
+}
 static inline struct bpf_trampoline *bpf_trampoline_get(u64 key,
 							struct bpf_attach_target_info *tgt_info)
 {
@@ -1483,6 +1501,9 @@  struct bpf_prog_aux {
 	bool xdp_has_frags;
 	bool exception_cb;
 	bool exception_boundary;
+	bool is_extended; /* true if extended by freplace program */
+	u64 prog_array_member_cnt; /* counts how many times as member of prog_array */
+	struct mutex ext_mutex; /* mutex for is_extended and prog_array_member_cnt */
 	struct bpf_arena *arena;
 	/* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
 	const struct btf_type *attach_func_proto;
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 79660e3fca4c1..f9bd63a74eee7 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -947,6 +947,7 @@  static void *prog_fd_array_get_ptr(struct bpf_map *map,
 				   struct file *map_file, int fd)
 {
 	struct bpf_prog *prog = bpf_prog_get(fd);
+	bool is_extended;
 
 	if (IS_ERR(prog))
 		return prog;
@@ -956,13 +957,33 @@  static void *prog_fd_array_get_ptr(struct bpf_map *map,
 		return ERR_PTR(-EINVAL);
 	}
 
+	mutex_lock(&prog->aux->ext_mutex);
+	is_extended = prog->aux->is_extended;
+	if (!is_extended)
+		prog->aux->prog_array_member_cnt++;
+	mutex_unlock(&prog->aux->ext_mutex);
+	if (is_extended) {
+		/* Extended prog can not be tail callee. It's to prevent a
+		 * potential infinite loop like:
+		 * tail callee prog entry -> tail callee prog subprog ->
+		 * freplace prog entry --tailcall-> tail callee prog entry.
+		 */
+		bpf_prog_put(prog);
+		return ERR_PTR(-EBUSY);
+	}
+
 	return prog;
 }
 
 static void prog_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer)
 {
+	struct bpf_prog *prog = ptr;
+
+	mutex_lock(&prog->aux->ext_mutex);
+	prog->aux->prog_array_member_cnt--;
+	mutex_unlock(&prog->aux->ext_mutex);
 	/* bpf_prog is freed after one RCU or tasks trace grace period */
-	bpf_prog_put(ptr);
+	bpf_prog_put(prog);
 }
 
 static u32 prog_fd_array_sys_lookup_elem(void *ptr)
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 5e77c58e06010..233ea78f8f1bd 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -131,6 +131,7 @@  struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
 	INIT_LIST_HEAD_RCU(&fp->aux->ksym_prefix.lnode);
 #endif
 	mutex_init(&fp->aux->used_maps_mutex);
+	mutex_init(&fp->aux->ext_mutex);
 	mutex_init(&fp->aux->dst_mutex);
 
 	return fp;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index a8f1808a1ca54..4a5a44bbb5f50 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3212,15 +3212,21 @@  static void bpf_tracing_link_release(struct bpf_link *link)
 {
 	struct bpf_tracing_link *tr_link =
 		container_of(link, struct bpf_tracing_link, link.link);
+	struct bpf_prog *tgt_prog = tr_link->tgt_prog;
 
-	WARN_ON_ONCE(bpf_trampoline_unlink_prog(&tr_link->link,
-						tr_link->trampoline));
+	if (link->prog->type == BPF_PROG_TYPE_EXT)
+		WARN_ON_ONCE(bpf_extension_unlink_prog(&tr_link->link,
+						       tr_link->trampoline,
+						       tgt_prog));
+	else
+		WARN_ON_ONCE(bpf_trampoline_unlink_prog(&tr_link->link,
+							tr_link->trampoline));
 
 	bpf_trampoline_put(tr_link->trampoline);
 
 	/* tgt_prog is NULL if target is a kernel function */
-	if (tr_link->tgt_prog)
-		bpf_prog_put(tr_link->tgt_prog);
+	if (tgt_prog)
+		bpf_prog_put(tgt_prog);
 }
 
 static void bpf_tracing_link_dealloc(struct bpf_link *link)
@@ -3354,7 +3360,7 @@  static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 	 *   in prog->aux
 	 *
 	 * - if prog->aux->dst_trampoline is NULL, the program has already been
-         *   attached to a target and its initial target was cleared (below)
+	 *   attached to a target and its initial target was cleared (below)
 	 *
 	 * - if tgt_prog != NULL, the caller specified tgt_prog_fd +
 	 *   target_btf_id using the link_create API.
@@ -3429,7 +3435,10 @@  static int bpf_tracing_prog_attach(struct bpf_prog *prog,
 	if (err)
 		goto out_unlock;
 
-	err = bpf_trampoline_link_prog(&link->link, tr);
+	if (prog->type == BPF_PROG_TYPE_EXT)
+		err = bpf_extension_link_prog(&link->link, tr, tgt_prog);
+	else
+		err = bpf_trampoline_link_prog(&link->link, tr);
 	if (err) {
 		bpf_link_cleanup(&link_primer);
 		link = NULL;
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index f8302a5ca400d..b14f56046ad4e 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -580,6 +580,35 @@  int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline
 	return err;
 }
 
+int bpf_extension_link_prog(struct bpf_tramp_link *link,
+			    struct bpf_trampoline *tr,
+			    struct bpf_prog *tgt_prog)
+{
+	struct bpf_prog_aux *aux = tgt_prog->aux;
+	int err;
+
+	mutex_lock(&aux->ext_mutex);
+	if (aux->prog_array_member_cnt) {
+		/* Program extensions can not extend target prog when the target
+		 * prog has been updated to any prog_array map as tail callee.
+		 * It's to prevent a potential infinite loop like:
+		 * tgt prog entry -> tgt prog subprog -> freplace prog entry
+		 * --tailcall-> tgt prog entry.
+		 */
+		err = -EBUSY;
+		goto out_unlock;
+	}
+
+	err = bpf_trampoline_link_prog(link, tr);
+	if (err)
+		goto out_unlock;
+
+	aux->is_extended = true;
+out_unlock:
+	mutex_unlock(&aux->ext_mutex);
+	return err;
+}
+
 static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
 {
 	enum bpf_tramp_prog_type kind;
@@ -609,6 +638,20 @@  int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampolin
 	return err;
 }
 
+int bpf_extension_unlink_prog(struct bpf_tramp_link *link,
+			      struct bpf_trampoline *tr,
+			      struct bpf_prog *tgt_prog)
+{
+	struct bpf_prog_aux *aux = tgt_prog->aux;
+	int err;
+
+	mutex_lock(&aux->ext_mutex);
+	err = bpf_trampoline_unlink_prog(link, tr);
+	aux->is_extended = false;
+	mutex_unlock(&aux->ext_mutex);
+	return err;
+}
+
 #if defined(CONFIG_CGROUP_BPF) && defined(CONFIG_BPF_LSM)
 static void bpf_shim_tramp_link_release(struct bpf_link *link)
 {