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