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
,
40 .ret_type
= RET_PTR_TO_MAP_VALUE_OR_NULL
,
41 .arg1_type
= ARG_CONST_MAP_PTR
,
42 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
45 BPF_CALL_4(bpf_map_update_elem
, struct bpf_map
*, map
, void *, key
,
46 void *, value
, u64
, flags
)
48 WARN_ON_ONCE(!rcu_read_lock_held());
49 return map
->ops
->map_update_elem(map
, key
, value
, flags
);
52 const struct bpf_func_proto bpf_map_update_elem_proto
= {
53 .func
= bpf_map_update_elem
,
56 .ret_type
= RET_INTEGER
,
57 .arg1_type
= ARG_CONST_MAP_PTR
,
58 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
59 .arg3_type
= ARG_PTR_TO_MAP_VALUE
,
60 .arg4_type
= ARG_ANYTHING
,
63 BPF_CALL_2(bpf_map_delete_elem
, struct bpf_map
*, map
, void *, key
)
65 WARN_ON_ONCE(!rcu_read_lock_held());
66 return map
->ops
->map_delete_elem(map
, key
);
69 const struct bpf_func_proto bpf_map_delete_elem_proto
= {
70 .func
= bpf_map_delete_elem
,
73 .ret_type
= RET_INTEGER
,
74 .arg1_type
= ARG_CONST_MAP_PTR
,
75 .arg2_type
= ARG_PTR_TO_MAP_KEY
,
78 const struct bpf_func_proto bpf_get_prandom_u32_proto
= {
79 .func
= bpf_user_rnd_u32
,
81 .ret_type
= RET_INTEGER
,
84 BPF_CALL_0(bpf_get_smp_processor_id
)
86 return smp_processor_id();
89 const struct bpf_func_proto bpf_get_smp_processor_id_proto
= {
90 .func
= bpf_get_smp_processor_id
,
92 .ret_type
= RET_INTEGER
,
95 BPF_CALL_0(bpf_ktime_get_ns
)
97 /* NMI safe access to clock monotonic */
98 return ktime_get_mono_fast_ns();
101 const struct bpf_func_proto bpf_ktime_get_ns_proto
= {
102 .func
= bpf_ktime_get_ns
,
104 .ret_type
= RET_INTEGER
,
107 BPF_CALL_0(bpf_get_current_pid_tgid
)
109 struct task_struct
*task
= current
;
114 return (u64
) task
->tgid
<< 32 | task
->pid
;
117 const struct bpf_func_proto bpf_get_current_pid_tgid_proto
= {
118 .func
= bpf_get_current_pid_tgid
,
120 .ret_type
= RET_INTEGER
,
123 BPF_CALL_0(bpf_get_current_uid_gid
)
125 struct task_struct
*task
= current
;
132 current_uid_gid(&uid
, &gid
);
133 return (u64
) from_kgid(&init_user_ns
, gid
) << 32 |
134 from_kuid(&init_user_ns
, uid
);
137 const struct bpf_func_proto bpf_get_current_uid_gid_proto
= {
138 .func
= bpf_get_current_uid_gid
,
140 .ret_type
= RET_INTEGER
,
143 BPF_CALL_2(bpf_get_current_comm
, char *, buf
, u32
, size
)
145 struct task_struct
*task
= current
;
150 strncpy(buf
, task
->comm
, size
);
152 /* Verifier guarantees that size > 0. For task->comm exceeding
153 * size, guarantee that buf is %NUL-terminated. Unconditionally
154 * done here to save the size test.
159 memset(buf
, 0, size
);
163 const struct bpf_func_proto bpf_get_current_comm_proto
= {
164 .func
= bpf_get_current_comm
,
166 .ret_type
= RET_INTEGER
,
167 .arg1_type
= ARG_PTR_TO_RAW_STACK
,
168 .arg2_type
= ARG_CONST_STACK_SIZE
,