xref: /linux/tools/testing/selftests/bpf/progs/wakeup_source_fail.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
19ef64711SSamuel Wu // SPDX-License-Identifier: GPL-2.0
29ef64711SSamuel Wu /* Copyright 2026 Google LLC */
39ef64711SSamuel Wu 
49ef64711SSamuel Wu #include <vmlinux.h>
59ef64711SSamuel Wu #include <bpf/bpf_helpers.h>
69ef64711SSamuel Wu #include "bpf_misc.h"
79ef64711SSamuel Wu 
89ef64711SSamuel Wu struct bpf_ws_lock;
99ef64711SSamuel Wu 
109ef64711SSamuel Wu struct bpf_ws_lock *bpf_wakeup_sources_read_lock(void) __ksym;
119ef64711SSamuel Wu void bpf_wakeup_sources_read_unlock(struct bpf_ws_lock *lock) __ksym;
129ef64711SSamuel Wu void *bpf_wakeup_sources_get_head(void) __ksym;
139ef64711SSamuel Wu 
149ef64711SSamuel Wu SEC("syscall")
159ef64711SSamuel Wu __failure __msg("BPF_EXIT instruction in main prog would lead to reference leak")
169ef64711SSamuel Wu int wakeup_source_lock_no_unlock(void *ctx)
179ef64711SSamuel Wu {
189ef64711SSamuel Wu 	struct bpf_ws_lock *lock;
199ef64711SSamuel Wu 
209ef64711SSamuel Wu 	lock = bpf_wakeup_sources_read_lock();
219ef64711SSamuel Wu 	if (!lock)
229ef64711SSamuel Wu 		return 0;
239ef64711SSamuel Wu 
249ef64711SSamuel Wu 	return 0;
259ef64711SSamuel Wu }
269ef64711SSamuel Wu 
279ef64711SSamuel Wu SEC("syscall")
289ef64711SSamuel Wu __failure __msg("access beyond struct")
299ef64711SSamuel Wu int wakeup_source_access_lock_fields(void *ctx)
309ef64711SSamuel Wu {
319ef64711SSamuel Wu 	struct bpf_ws_lock *lock;
329ef64711SSamuel Wu 	int val;
339ef64711SSamuel Wu 
349ef64711SSamuel Wu 	lock = bpf_wakeup_sources_read_lock();
359ef64711SSamuel Wu 	if (!lock)
369ef64711SSamuel Wu 		return 0;
379ef64711SSamuel Wu 
389ef64711SSamuel Wu 	val = *(int *)lock;
399ef64711SSamuel Wu 
409ef64711SSamuel Wu 	bpf_wakeup_sources_read_unlock(lock);
419ef64711SSamuel Wu 	return val;
429ef64711SSamuel Wu }
439ef64711SSamuel Wu 
449ef64711SSamuel Wu SEC("syscall")
45*bcfcb15fSAmery Hung __failure __msg("release kfunc bpf_wakeup_sources_read_unlock expects referenced PTR_TO_BTF_ID passed to R1")
469ef64711SSamuel Wu int wakeup_source_unlock_no_lock(void *ctx)
479ef64711SSamuel Wu {
489ef64711SSamuel Wu 	struct bpf_ws_lock *lock = (void *)0x1;
499ef64711SSamuel Wu 
509ef64711SSamuel Wu 	bpf_wakeup_sources_read_unlock(lock);
519ef64711SSamuel Wu 
529ef64711SSamuel Wu 	return 0;
539ef64711SSamuel Wu }
549ef64711SSamuel Wu 
559ef64711SSamuel Wu SEC("syscall")
569ef64711SSamuel Wu __failure __msg("Possibly NULL pointer passed to trusted")
579ef64711SSamuel Wu int wakeup_source_unlock_null(void *ctx)
589ef64711SSamuel Wu {
599ef64711SSamuel Wu 	bpf_wakeup_sources_read_unlock(NULL);
609ef64711SSamuel Wu 
619ef64711SSamuel Wu 	return 0;
629ef64711SSamuel Wu }
639ef64711SSamuel Wu 
649ef64711SSamuel Wu SEC("syscall")
659ef64711SSamuel Wu __failure __msg("R0 invalid mem access 'scalar'")
669ef64711SSamuel Wu int wakeup_source_unsafe_dereference(void *ctx)
679ef64711SSamuel Wu {
689ef64711SSamuel Wu 	struct list_head *head = bpf_wakeup_sources_get_head();
699ef64711SSamuel Wu 
709ef64711SSamuel Wu 	if (head->next)
719ef64711SSamuel Wu 		return 1;
729ef64711SSamuel Wu 
739ef64711SSamuel Wu 	return 0;
749ef64711SSamuel Wu }
759ef64711SSamuel Wu 
769ef64711SSamuel Wu char _license[] SEC("license") = "GPL";
77