-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'fix-resource-leak-checks-for-tail-calls'
Kumar Kartikeya Dwivedi says: ==================== Fix resource leak checks for tail calls This set contains a fix for detecting unreleased RCU read locks or unfinished preempt_disable sections when performing a tail call. Spin locks are prevented by accident since they don't allow any function calls, including tail calls (modelled as call instruction to a helper), so we ensure they are checked as well, in preparation for relaxing function call restricton for critical sections in the future. Then, in the second patch, all the checks for reference leaks and locks are unified into a single function that can be called from different places. This unification patch is kept separate and placed after the fix to allow independent backport of the fix to older kernels without a depdendency on the clean up. Naturally, this creates a divergence in the disparate error messages, therefore selftests that rely on the exact error strings need to be updated to match the new verifier log message. A selftest is included to ensure no regressions occur wrt this behavior. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
- Loading branch information
Showing
7 changed files
with
118 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_core_read.h> | ||
|
||
#include "bpf_misc.h" | ||
#include "bpf_experimental.h" | ||
|
||
extern void bpf_rcu_read_lock(void) __ksym; | ||
extern void bpf_rcu_read_unlock(void) __ksym; | ||
|
||
#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8))) | ||
|
||
private(A) struct bpf_spin_lock lock; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_PROG_ARRAY); | ||
__uint(max_entries, 3); | ||
__uint(key_size, sizeof(__u32)); | ||
__uint(value_size, sizeof(__u32)); | ||
} jmp_table SEC(".maps"); | ||
|
||
SEC("?tc") | ||
__failure __msg("function calls are not allowed while holding a lock") | ||
int reject_tail_call_spin_lock(struct __sk_buff *ctx) | ||
{ | ||
bpf_spin_lock(&lock); | ||
bpf_tail_call_static(ctx, &jmp_table, 0); | ||
return 0; | ||
} | ||
|
||
SEC("?tc") | ||
__failure __msg("tail_call cannot be used inside bpf_rcu_read_lock-ed region") | ||
int reject_tail_call_rcu_lock(struct __sk_buff *ctx) | ||
{ | ||
bpf_rcu_read_lock(); | ||
bpf_tail_call_static(ctx, &jmp_table, 0); | ||
bpf_rcu_read_unlock(); | ||
return 0; | ||
} | ||
|
||
SEC("?tc") | ||
__failure __msg("tail_call cannot be used inside bpf_preempt_disable-ed region") | ||
int reject_tail_call_preempt_lock(struct __sk_buff *ctx) | ||
{ | ||
bpf_guard_preempt(); | ||
bpf_tail_call_static(ctx, &jmp_table, 0); | ||
return 0; | ||
} | ||
|
||
SEC("?tc") | ||
__failure __msg("tail_call would lead to reference leak") | ||
int reject_tail_call_ref(struct __sk_buff *ctx) | ||
{ | ||
struct foo { int i; } *p; | ||
|
||
p = bpf_obj_new(typeof(*p)); | ||
bpf_tail_call_static(ctx, &jmp_table, 0); | ||
return 0; | ||
} | ||
|
||
char _license[] SEC("license") = "GPL"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters