17bd1590dSMartin KaFai Lau // SPDX-License-Identifier: GPL-2.0 27bd1590dSMartin KaFai Lau /* Copyright (c) 2021 Facebook */ 3c1ff181fSKumar Kartikeya Dwivedi #include <vmlinux.h> 47bd1590dSMartin KaFai Lau #include <bpf/bpf_helpers.h> 57bd1590dSMartin KaFai Lau 67bd1590dSMartin KaFai Lau extern int bpf_kfunc_call_test2(struct sock *sk, __u32 a, __u32 b) __ksym; 77bd1590dSMartin KaFai Lau extern __u64 bpf_kfunc_call_test1(struct sock *sk, __u32 a, __u64 b, 87bd1590dSMartin KaFai Lau __u32 c, __u64 d) __ksym; 97bd1590dSMartin KaFai Lau 10c1ff181fSKumar Kartikeya Dwivedi extern struct prog_test_ref_kfunc *bpf_kfunc_call_test_acquire(unsigned long *sp) __ksym; 11c1ff181fSKumar Kartikeya Dwivedi extern void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p) __ksym; 12c1ff181fSKumar Kartikeya Dwivedi extern void bpf_kfunc_call_test_pass_ctx(struct __sk_buff *skb) __ksym; 13c1ff181fSKumar Kartikeya Dwivedi extern void bpf_kfunc_call_test_pass1(struct prog_test_pass1 *p) __ksym; 14c1ff181fSKumar Kartikeya Dwivedi extern void bpf_kfunc_call_test_pass2(struct prog_test_pass2 *p) __ksym; 15c1ff181fSKumar Kartikeya Dwivedi extern void bpf_kfunc_call_test_mem_len_pass1(void *mem, int len) __ksym; 16c1ff181fSKumar Kartikeya Dwivedi extern void bpf_kfunc_call_test_mem_len_fail2(__u64 *mem, int len) __ksym; 17*22ed8d5aSBenjamin Tissoires extern int *bpf_kfunc_call_test_get_rdwr_mem(struct prog_test_ref_kfunc *p, const int rdwr_buf_size) __ksym; 18*22ed8d5aSBenjamin Tissoires extern int *bpf_kfunc_call_test_get_rdonly_mem(struct prog_test_ref_kfunc *p, const int rdonly_buf_size) __ksym; 19c1ff181fSKumar Kartikeya Dwivedi 20c22bdd28SAndrii Nakryiko SEC("tc") 217bd1590dSMartin KaFai Lau int kfunc_call_test2(struct __sk_buff *skb) 227bd1590dSMartin KaFai Lau { 237bd1590dSMartin KaFai Lau struct bpf_sock *sk = skb->sk; 247bd1590dSMartin KaFai Lau 257bd1590dSMartin KaFai Lau if (!sk) 267bd1590dSMartin KaFai Lau return -1; 277bd1590dSMartin KaFai Lau 287bd1590dSMartin KaFai Lau sk = bpf_sk_fullsock(sk); 297bd1590dSMartin KaFai Lau if (!sk) 307bd1590dSMartin KaFai Lau return -1; 317bd1590dSMartin KaFai Lau 327bd1590dSMartin KaFai Lau return bpf_kfunc_call_test2((struct sock *)sk, 1, 2); 337bd1590dSMartin KaFai Lau } 347bd1590dSMartin KaFai Lau 35c22bdd28SAndrii Nakryiko SEC("tc") 367bd1590dSMartin KaFai Lau int kfunc_call_test1(struct __sk_buff *skb) 377bd1590dSMartin KaFai Lau { 387bd1590dSMartin KaFai Lau struct bpf_sock *sk = skb->sk; 397bd1590dSMartin KaFai Lau __u64 a = 1ULL << 32; 407bd1590dSMartin KaFai Lau __u32 ret; 417bd1590dSMartin KaFai Lau 427bd1590dSMartin KaFai Lau if (!sk) 437bd1590dSMartin KaFai Lau return -1; 447bd1590dSMartin KaFai Lau 457bd1590dSMartin KaFai Lau sk = bpf_sk_fullsock(sk); 467bd1590dSMartin KaFai Lau if (!sk) 477bd1590dSMartin KaFai Lau return -1; 487bd1590dSMartin KaFai Lau 497bd1590dSMartin KaFai Lau a = bpf_kfunc_call_test1((struct sock *)sk, 1, a | 2, 3, a | 4); 507bd1590dSMartin KaFai Lau ret = a >> 32; /* ret should be 2 */ 517bd1590dSMartin KaFai Lau ret += (__u32)a; /* ret should be 12 */ 527bd1590dSMartin KaFai Lau 537bd1590dSMartin KaFai Lau return ret; 547bd1590dSMartin KaFai Lau } 557bd1590dSMartin KaFai Lau 56c1ff181fSKumar Kartikeya Dwivedi SEC("tc") 57c1ff181fSKumar Kartikeya Dwivedi int kfunc_call_test_ref_btf_id(struct __sk_buff *skb) 58c1ff181fSKumar Kartikeya Dwivedi { 59c1ff181fSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *pt; 60c1ff181fSKumar Kartikeya Dwivedi unsigned long s = 0; 61c1ff181fSKumar Kartikeya Dwivedi int ret = 0; 62c1ff181fSKumar Kartikeya Dwivedi 63c1ff181fSKumar Kartikeya Dwivedi pt = bpf_kfunc_call_test_acquire(&s); 64c1ff181fSKumar Kartikeya Dwivedi if (pt) { 65c1ff181fSKumar Kartikeya Dwivedi if (pt->a != 42 || pt->b != 108) 66c1ff181fSKumar Kartikeya Dwivedi ret = -1; 67c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(pt); 68c1ff181fSKumar Kartikeya Dwivedi } 69c1ff181fSKumar Kartikeya Dwivedi return ret; 70c1ff181fSKumar Kartikeya Dwivedi } 71c1ff181fSKumar Kartikeya Dwivedi 72c1ff181fSKumar Kartikeya Dwivedi SEC("tc") 73c1ff181fSKumar Kartikeya Dwivedi int kfunc_call_test_pass(struct __sk_buff *skb) 74c1ff181fSKumar Kartikeya Dwivedi { 75c1ff181fSKumar Kartikeya Dwivedi struct prog_test_pass1 p1 = {}; 76c1ff181fSKumar Kartikeya Dwivedi struct prog_test_pass2 p2 = {}; 77c1ff181fSKumar Kartikeya Dwivedi short a = 0; 78c1ff181fSKumar Kartikeya Dwivedi __u64 b = 0; 79c1ff181fSKumar Kartikeya Dwivedi long c = 0; 80c1ff181fSKumar Kartikeya Dwivedi char d = 0; 81c1ff181fSKumar Kartikeya Dwivedi int e = 0; 82c1ff181fSKumar Kartikeya Dwivedi 83c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_pass_ctx(skb); 84c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_pass1(&p1); 85c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_pass2(&p2); 86c1ff181fSKumar Kartikeya Dwivedi 87c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_mem_len_pass1(&a, sizeof(a)); 88c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_mem_len_pass1(&b, sizeof(b)); 89c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_mem_len_pass1(&c, sizeof(c)); 90c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_mem_len_pass1(&d, sizeof(d)); 91c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_mem_len_pass1(&e, sizeof(e)); 92c1ff181fSKumar Kartikeya Dwivedi bpf_kfunc_call_test_mem_len_fail2(&b, -1); 93c1ff181fSKumar Kartikeya Dwivedi 94c1ff181fSKumar Kartikeya Dwivedi return 0; 95c1ff181fSKumar Kartikeya Dwivedi } 96c1ff181fSKumar Kartikeya Dwivedi 97fb66223aSBenjamin Tissoires struct syscall_test_args { 98fb66223aSBenjamin Tissoires __u8 data[16]; 99fb66223aSBenjamin Tissoires size_t size; 100fb66223aSBenjamin Tissoires }; 101fb66223aSBenjamin Tissoires 102fb66223aSBenjamin Tissoires SEC("syscall") 103fb66223aSBenjamin Tissoires int kfunc_syscall_test(struct syscall_test_args *args) 104fb66223aSBenjamin Tissoires { 105fb66223aSBenjamin Tissoires const long size = args->size; 106fb66223aSBenjamin Tissoires 107fb66223aSBenjamin Tissoires if (size > sizeof(args->data)) 108fb66223aSBenjamin Tissoires return -7; /* -E2BIG */ 109fb66223aSBenjamin Tissoires 110fb66223aSBenjamin Tissoires bpf_kfunc_call_test_mem_len_pass1(&args->data, sizeof(args->data)); 111fb66223aSBenjamin Tissoires bpf_kfunc_call_test_mem_len_pass1(&args->data, sizeof(*args)); 112fb66223aSBenjamin Tissoires bpf_kfunc_call_test_mem_len_pass1(&args->data, size); 113fb66223aSBenjamin Tissoires 114fb66223aSBenjamin Tissoires return 0; 115fb66223aSBenjamin Tissoires } 116fb66223aSBenjamin Tissoires 117fb66223aSBenjamin Tissoires SEC("syscall") 118fb66223aSBenjamin Tissoires int kfunc_syscall_test_null(struct syscall_test_args *args) 119fb66223aSBenjamin Tissoires { 120fb66223aSBenjamin Tissoires /* Must be called with args as a NULL pointer 121fb66223aSBenjamin Tissoires * we do not check for it to have the verifier consider that 122fb66223aSBenjamin Tissoires * the pointer might not be null, and so we can load it. 123fb66223aSBenjamin Tissoires * 124fb66223aSBenjamin Tissoires * So the following can not be added: 125fb66223aSBenjamin Tissoires * 126fb66223aSBenjamin Tissoires * if (args) 127fb66223aSBenjamin Tissoires * return -22; 128fb66223aSBenjamin Tissoires */ 129fb66223aSBenjamin Tissoires 130fb66223aSBenjamin Tissoires bpf_kfunc_call_test_mem_len_pass1(args, 0); 131fb66223aSBenjamin Tissoires 132fb66223aSBenjamin Tissoires return 0; 133fb66223aSBenjamin Tissoires } 134fb66223aSBenjamin Tissoires 135*22ed8d5aSBenjamin Tissoires SEC("tc") 136*22ed8d5aSBenjamin Tissoires int kfunc_call_test_get_mem(struct __sk_buff *skb) 137*22ed8d5aSBenjamin Tissoires { 138*22ed8d5aSBenjamin Tissoires struct prog_test_ref_kfunc *pt; 139*22ed8d5aSBenjamin Tissoires unsigned long s = 0; 140*22ed8d5aSBenjamin Tissoires int *p = NULL; 141*22ed8d5aSBenjamin Tissoires int ret = 0; 142*22ed8d5aSBenjamin Tissoires 143*22ed8d5aSBenjamin Tissoires pt = bpf_kfunc_call_test_acquire(&s); 144*22ed8d5aSBenjamin Tissoires if (pt) { 145*22ed8d5aSBenjamin Tissoires p = bpf_kfunc_call_test_get_rdwr_mem(pt, 2 * sizeof(int)); 146*22ed8d5aSBenjamin Tissoires if (p) { 147*22ed8d5aSBenjamin Tissoires p[0] = 42; 148*22ed8d5aSBenjamin Tissoires ret = p[1]; /* 108 */ 149*22ed8d5aSBenjamin Tissoires } else { 150*22ed8d5aSBenjamin Tissoires ret = -1; 151*22ed8d5aSBenjamin Tissoires } 152*22ed8d5aSBenjamin Tissoires 153*22ed8d5aSBenjamin Tissoires if (ret >= 0) { 154*22ed8d5aSBenjamin Tissoires p = bpf_kfunc_call_test_get_rdonly_mem(pt, 2 * sizeof(int)); 155*22ed8d5aSBenjamin Tissoires if (p) 156*22ed8d5aSBenjamin Tissoires ret = p[0]; /* 42 */ 157*22ed8d5aSBenjamin Tissoires else 158*22ed8d5aSBenjamin Tissoires ret = -1; 159*22ed8d5aSBenjamin Tissoires } 160*22ed8d5aSBenjamin Tissoires 161*22ed8d5aSBenjamin Tissoires bpf_kfunc_call_test_release(pt); 162*22ed8d5aSBenjamin Tissoires } 163*22ed8d5aSBenjamin Tissoires return ret; 164*22ed8d5aSBenjamin Tissoires } 165*22ed8d5aSBenjamin Tissoires 1667bd1590dSMartin KaFai Lau char _license[] SEC("license") = "GPL"; 167