1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2021 Facebook */ 3 #include <vmlinux.h> 4 #include <bpf/bpf_helpers.h> 5 #include "../bpf_testmod/bpf_testmod_kfunc.h" 6 7 struct syscall_test_args { 8 __u8 data[16]; 9 size_t size; 10 }; 11 12 SEC("?syscall") 13 int kfunc_syscall_test_fail(struct syscall_test_args *args) 14 { 15 bpf_kfunc_call_test_mem_len_pass1(&args->data, sizeof(*args) + 1); 16 17 return 0; 18 } 19 20 SEC("?syscall") 21 int kfunc_syscall_test_null_fail(struct syscall_test_args *args) 22 { 23 /* Must be called with args as a NULL pointer 24 * we do not check for it to have the verifier consider that 25 * the pointer might not be null, and so we can load it. 26 * 27 * So the following can not be added: 28 * 29 * if (args) 30 * return -22; 31 */ 32 33 bpf_kfunc_call_test_mem_len_pass1(args, sizeof(*args)); 34 35 return 0; 36 } 37 38 SEC("?tc") 39 int kfunc_call_test_get_mem_fail_rdonly(struct __sk_buff *skb) 40 { 41 struct prog_test_ref_kfunc *pt; 42 unsigned long s = 0; 43 int *p = NULL; 44 int ret = 0; 45 46 pt = bpf_kfunc_call_test_acquire(&s); 47 if (pt) { 48 p = bpf_kfunc_call_test_get_rdonly_mem(pt, 2 * sizeof(int)); 49 if (p) 50 p[0] = 42; /* this is a read-only buffer, so -EACCES */ 51 else 52 ret = -1; 53 54 bpf_kfunc_call_test_release(pt); 55 } 56 return ret; 57 } 58 59 SEC("?tc") 60 int kfunc_call_test_get_mem_fail_use_after_free(struct __sk_buff *skb) 61 { 62 struct prog_test_ref_kfunc *pt; 63 unsigned long s = 0; 64 int *p = NULL; 65 int ret = 0; 66 67 pt = bpf_kfunc_call_test_acquire(&s); 68 if (pt) { 69 p = bpf_kfunc_call_test_get_rdwr_mem(pt, 2 * sizeof(int)); 70 if (p) { 71 p[0] = 42; 72 ret = p[1]; /* 108 */ 73 } else { 74 ret = -1; 75 } 76 77 bpf_kfunc_call_test_release(pt); 78 } 79 if (p) 80 ret = p[0]; /* p is not valid anymore */ 81 82 return ret; 83 } 84 85 SEC("?tc") 86 int kfunc_call_test_get_mem_fail_oob(struct __sk_buff *skb) 87 { 88 struct prog_test_ref_kfunc *pt; 89 unsigned long s = 0; 90 int *p = NULL; 91 int ret = 0; 92 93 pt = bpf_kfunc_call_test_acquire(&s); 94 if (pt) { 95 p = bpf_kfunc_call_test_get_rdonly_mem(pt, 2 * sizeof(int)); 96 if (p) 97 ret = p[2 * sizeof(int)]; /* oob access, so -EACCES */ 98 else 99 ret = -1; 100 101 bpf_kfunc_call_test_release(pt); 102 } 103 return ret; 104 } 105 106 int not_const_size = 2 * sizeof(int); 107 108 SEC("?tc") 109 int kfunc_call_test_get_mem_fail_not_const(struct __sk_buff *skb) 110 { 111 struct prog_test_ref_kfunc *pt; 112 unsigned long s = 0; 113 int *p = NULL; 114 int ret = 0; 115 116 pt = bpf_kfunc_call_test_acquire(&s); 117 if (pt) { 118 p = bpf_kfunc_call_test_get_rdonly_mem(pt, not_const_size); /* non const size, -EINVAL */ 119 if (p) 120 ret = p[0]; 121 else 122 ret = -1; 123 124 bpf_kfunc_call_test_release(pt); 125 } 126 return ret; 127 } 128 129 SEC("?tc") 130 int kfunc_call_test_mem_acquire_fail(struct __sk_buff *skb) 131 { 132 struct prog_test_ref_kfunc *pt; 133 unsigned long s = 0; 134 int *p = NULL; 135 int ret = 0; 136 137 pt = bpf_kfunc_call_test_acquire(&s); 138 if (pt) { 139 /* we are failing on this one, because we are not acquiring a PTR_TO_BTF_ID (a struct ptr) */ 140 p = bpf_kfunc_call_test_acq_rdonly_mem(pt, 2 * sizeof(int)); 141 if (p) 142 ret = p[0]; 143 else 144 ret = -1; 145 146 bpf_kfunc_call_int_mem_release(p); 147 148 bpf_kfunc_call_test_release(pt); 149 } 150 return ret; 151 } 152 153 char _license[] SEC("license") = "GPL"; 154