1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ 3 4 #include <stdbool.h> 5 #include <errno.h> 6 #include <string.h> 7 #include <linux/bpf.h> 8 #include <bpf/bpf_helpers.h> 9 #include "bpf_misc.h" 10 11 int arr[1]; 12 int unkn_idx; 13 14 __noinline long global_bad(void) 15 { 16 return arr[unkn_idx]; /* BOOM */ 17 } 18 19 __noinline long global_good(void) 20 { 21 return arr[0]; 22 } 23 24 __noinline long global_calls_bad(void) 25 { 26 return global_good() + global_bad() /* does BOOM indirectly */; 27 } 28 29 __noinline long global_calls_good_only(void) 30 { 31 return global_good(); 32 } 33 34 SEC("?raw_tp") 35 __success __log_level(2) 36 /* main prog is validated completely first */ 37 __msg("('global_calls_good_only') is global and assumed valid.") 38 __msg("1: (95) exit") 39 /* eventually global_good() is transitively validated as well */ 40 __msg("Validating global_good() func") 41 __msg("('global_good') is safe for any args that match its prototype") 42 int chained_global_func_calls_success(void) 43 { 44 return global_calls_good_only(); 45 } 46 47 SEC("?raw_tp") 48 __failure __log_level(2) 49 /* main prog validated successfully first */ 50 __msg("1: (95) exit") 51 /* eventually we validate global_bad() and fail */ 52 __msg("Validating global_bad() func") 53 __msg("math between map_value pointer and register") /* BOOM */ 54 int chained_global_func_calls_bad(void) 55 { 56 return global_calls_bad(); 57 } 58 59 /* do out of bounds access forcing verifier to fail verification if this 60 * global func is called 61 */ 62 __noinline int global_unsupp(const int *mem) 63 { 64 if (!mem) 65 return 0; 66 return mem[100]; /* BOOM */ 67 } 68 69 const volatile bool skip_unsupp_global = true; 70 71 SEC("?raw_tp") 72 __success 73 int guarded_unsupp_global_called(void) 74 { 75 if (!skip_unsupp_global) 76 return global_unsupp(NULL); 77 return 0; 78 } 79 80 SEC("?raw_tp") 81 __failure __log_level(2) 82 __msg("Func#1 ('global_unsupp') is global and assumed valid.") 83 __msg("Validating global_unsupp() func#1...") 84 __msg("value is outside of the allowed memory range") 85 int unguarded_unsupp_global_called(void) 86 { 87 int x = 0; 88 89 return global_unsupp(&x); 90 } 91 92 char _license[] SEC("license") = "GPL"; 93