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