xref: /linux/tools/testing/selftests/bpf/progs/wakeup_source_fail.c (revision 84f7a49e76ec8e0a1e18f3758e89800f8cf8cfc6)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2026 Google LLC */
3 
4 #include <vmlinux.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 struct bpf_ws_lock;
9 
10 struct bpf_ws_lock *bpf_wakeup_sources_read_lock(void) __ksym;
11 void bpf_wakeup_sources_read_unlock(struct bpf_ws_lock *lock) __ksym;
12 void *bpf_wakeup_sources_get_head(void) __ksym;
13 
14 SEC("syscall")
15 __failure __msg("BPF_EXIT instruction in main prog would lead to reference leak")
16 int wakeup_source_lock_no_unlock(void *ctx)
17 {
18 	struct bpf_ws_lock *lock;
19 
20 	lock = bpf_wakeup_sources_read_lock();
21 	if (!lock)
22 		return 0;
23 
24 	return 0;
25 }
26 
27 SEC("syscall")
28 __failure __msg("access beyond struct")
29 int wakeup_source_access_lock_fields(void *ctx)
30 {
31 	struct bpf_ws_lock *lock;
32 	int val;
33 
34 	lock = bpf_wakeup_sources_read_lock();
35 	if (!lock)
36 		return 0;
37 
38 	val = *(int *)lock;
39 
40 	bpf_wakeup_sources_read_unlock(lock);
41 	return val;
42 }
43 
44 SEC("syscall")
45 __failure __msg("release kfunc bpf_wakeup_sources_read_unlock expects referenced PTR_TO_BTF_ID passed to R1")
46 int wakeup_source_unlock_no_lock(void *ctx)
47 {
48 	struct bpf_ws_lock *lock = (void *)0x1;
49 
50 	bpf_wakeup_sources_read_unlock(lock);
51 
52 	return 0;
53 }
54 
55 SEC("syscall")
56 __failure __msg("Possibly NULL pointer passed to trusted")
57 int wakeup_source_unlock_null(void *ctx)
58 {
59 	bpf_wakeup_sources_read_unlock(NULL);
60 
61 	return 0;
62 }
63 
64 SEC("syscall")
65 __failure __msg("R0 invalid mem access 'scalar'")
66 int wakeup_source_unsafe_dereference(void *ctx)
67 {
68 	struct list_head *head = bpf_wakeup_sources_get_head();
69 
70 	if (head->next)
71 		return 1;
72 
73 	return 0;
74 }
75 
76 char _license[] SEC("license") = "GPL";
77