1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2021 Google LLC
3
4 #include <linux/filter.h>
5 #include <linux/fuse.h>
6
7 static const struct bpf_func_proto *
fuse_prog_func_proto(enum bpf_func_id func_id,const struct bpf_prog * prog)8 fuse_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
9 {
10 switch (func_id) {
11 case BPF_FUNC_trace_printk:
12 return bpf_get_trace_printk_proto();
13
14 case BPF_FUNC_get_current_uid_gid:
15 return &bpf_get_current_uid_gid_proto;
16
17 case BPF_FUNC_get_current_pid_tgid:
18 return &bpf_get_current_pid_tgid_proto;
19
20 case BPF_FUNC_map_lookup_elem:
21 return &bpf_map_lookup_elem_proto;
22
23 case BPF_FUNC_map_update_elem:
24 return &bpf_map_update_elem_proto;
25
26 default:
27 pr_debug("Invalid fuse bpf func %d\n", func_id);
28 return NULL;
29 }
30 }
31
fuse_prog_is_valid_access(int off,int size,enum bpf_access_type type,const struct bpf_prog * prog,struct bpf_insn_access_aux * info)32 static bool fuse_prog_is_valid_access(int off, int size,
33 enum bpf_access_type type,
34 const struct bpf_prog *prog,
35 struct bpf_insn_access_aux *info)
36 {
37 int i;
38
39 if (off < 0 || off > offsetofend(struct fuse_bpf_args, out_args))
40 return false;
41
42 /* TODO This is garbage. Do it properly */
43 for (i = 0; i < 5; i++) {
44 if (off == offsetof(struct fuse_bpf_args, in_args[i].value)) {
45 info->reg_type = PTR_TO_RDONLY_BUF;
46 info->ctx_field_size = 256;
47 if (type != BPF_READ)
48 return false;
49 return true;
50 }
51 }
52 for (i = 0; i < 3; i++) {
53 if (off == offsetof(struct fuse_bpf_args, out_args[i].value)) {
54 info->reg_type = PTR_TO_RDWR_BUF;
55 info->ctx_field_size = 256;
56 return true;
57 }
58 }
59 if (type != BPF_READ)
60 return false;
61
62 return true;
63 }
64
65 const struct bpf_verifier_ops fuse_verifier_ops = {
66 .get_func_proto = fuse_prog_func_proto,
67 .is_valid_access = fuse_prog_is_valid_access,
68 };
69
70 const struct bpf_prog_ops fuse_prog_ops = {
71 };
72
73