1 /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 #include <linux/bpf.h>
13 #include <linux/rcupdate.h>
14 #include <linux/random.h>
15 #include <linux/smp.h>
16 #include <linux/ktime.h>
17 #include <linux/sched.h>
18 #include <linux/uidgid.h>
19 #include <linux/filter.h>
21 /* If kernel subsystem is allowing eBPF programs to call this function,
22 * inside its own verifier_ops->get_func_proto() callback it should return
23 * bpf_map_lookup_elem_proto, so that verifier can properly check the arguments
25 * Different map implementations will rely on rcu in map methods
26 * lookup/update/delete, therefore eBPF programs must run under rcu lock
27 * if program is allowed to access maps, so check rcu_read_lock_held in
28 * all three functions.
30 BPF_CALL_2(bpf_map_lookup_elem
, struct bpf_map
*, map
, void *, key
)
32 WARN_ON_ONCE(!rcu_read_lock_held());
33 return (unsigned long) map
->ops
->map_lookup_elem(map
, key
);
36 const struct bpf_func_proto bpf_map_lookup_elem_proto
= {
37 .func
= bpf_map_lookup_elem
,
39 .ret_type
= RET_PTR_TO_MAP_VALUE_OR_NULL
,
40 .arg1_type
= ARG_CONST_MAP_PTR
,
41 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
44 BPF_CALL_4(bpf_map_update_elem
, struct bpf_map
*, map
, void *, key
,
45 void *, value
, u64
, flags
)
47 WARN_ON_ONCE(!rcu_read_lock_held());
48 return map
->ops
->map_update_elem(map
, key
, value
, flags
);
51 const struct bpf_func_proto bpf_map_update_elem_proto
= {
52 .func
= bpf_map_update_elem
,
54 .ret_type
= RET_INTEGER
,
55 .arg1_type
= ARG_CONST_MAP_PTR
,
56 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
57 .arg3_type
= ARG_PTR_TO_MAP_VALUE
,
58 .arg4_type
= ARG_ANYTHING
,
61 BPF_CALL_2(bpf_map_delete_elem
, struct bpf_map
*, map
, void *, key
)
63 WARN_ON_ONCE(!rcu_read_lock_held());
64 return map
->ops
->map_delete_elem(map
, key
);
67 const struct bpf_func_proto bpf_map_delete_elem_proto
= {
68 .func
= bpf_map_delete_elem
,
70 .ret_type
= RET_INTEGER
,
71 .arg1_type
= ARG_CONST_MAP_PTR
,
72 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
75 const struct bpf_func_proto bpf_get_prandom_u32_proto
= {
76 .func
= bpf_user_rnd_u32
,
78 .ret_type
= RET_INTEGER
,
81 BPF_CALL_0(bpf_get_smp_processor_id
)
83 return smp_processor_id();
86 const struct bpf_func_proto bpf_get_smp_processor_id_proto
= {
87 .func
= bpf_get_smp_processor_id
,
89 .ret_type
= RET_INTEGER
,
92 BPF_CALL_0(bpf_ktime_get_ns
)
94 /* NMI safe access to clock monotonic */
95 return ktime_get_mono_fast_ns();
98 const struct bpf_func_proto bpf_ktime_get_ns_proto
= {
99 .func
= bpf_ktime_get_ns
,
101 .ret_type
= RET_INTEGER
,
104 BPF_CALL_0(bpf_get_current_pid_tgid
)
106 struct task_struct
*task
= current
;
111 return (u64
) task
->tgid
<< 32 | task
->pid
;
114 const struct bpf_func_proto bpf_get_current_pid_tgid_proto
= {
115 .func
= bpf_get_current_pid_tgid
,
117 .ret_type
= RET_INTEGER
,
120 BPF_CALL_0(bpf_get_current_uid_gid
)
122 struct task_struct
*task
= current
;
129 current_uid_gid(&uid
, &gid
);
130 return (u64
) from_kgid(&init_user_ns
, gid
) << 32 |
131 from_kuid(&init_user_ns
, uid
);
134 const struct bpf_func_proto bpf_get_current_uid_gid_proto
= {
135 .func
= bpf_get_current_uid_gid
,
137 .ret_type
= RET_INTEGER
,
140 BPF_CALL_2(bpf_get_current_comm
, char *, buf
, u32
, size
)
142 struct task_struct
*task
= current
;
147 strncpy(buf
, task
->comm
, size
);
149 /* Verifier guarantees that size > 0. For task->comm exceeding
150 * size, guarantee that buf is %NUL-terminated. Unconditionally
151 * done here to save the size test.
156 memset(buf
, 0, size
);
160 const struct bpf_func_proto bpf_get_current_comm_proto
= {
161 .func
= bpf_get_current_comm
,
163 .ret_type
= RET_INTEGER
,
164 .arg1_type
= ARG_PTR_TO_RAW_STACK
,
165 .arg2_type
= ARG_CONST_STACK_SIZE
,