blob: 2405feedb8c1bf5c411be645f84046f5fac9eb80 [file] [log] [blame]
Alexei Starovoitov99c55f72014-09-26 00:16:57 -07001/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
2 *
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.
6 *
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.
11 */
12#include <linux/bpf.h>
Daniel Borkmanna67edbf2017-01-25 02:28:18 +010013#include <linux/bpf_trace.h>
Alexei Starovoitov99c55f72014-09-26 00:16:57 -070014#include <linux/syscalls.h>
15#include <linux/slab.h>
Ingo Molnar3f07c012017-02-08 18:51:30 +010016#include <linux/sched/signal.h>
Daniel Borkmannd407bd22017-01-18 15:14:17 +010017#include <linux/vmalloc.h>
18#include <linux/mmzone.h>
Alexei Starovoitov99c55f72014-09-26 00:16:57 -070019#include <linux/anon_inodes.h>
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -070020#include <linux/file.h>
Alexei Starovoitov09756af2014-09-26 00:17:00 -070021#include <linux/license.h>
22#include <linux/filter.h>
Alexei Starovoitov25415172015-03-25 12:49:20 -070023#include <linux/version.h>
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +010024#include <linux/kernel.h>
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -070025#include <linux/idr.h>
Alexei Starovoitov99c55f72014-09-26 00:16:57 -070026
Alexei Starovoitovb121d1e2016-03-07 21:57:13 -080027DEFINE_PER_CPU(int, bpf_prog_active);
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -070028static DEFINE_IDR(prog_idr);
29static DEFINE_SPINLOCK(prog_idr_lock);
Martin KaFai Lauf3f1c052017-06-05 12:15:47 -070030static DEFINE_IDR(map_idr);
31static DEFINE_SPINLOCK(map_idr_lock);
Alexei Starovoitovb121d1e2016-03-07 21:57:13 -080032
Alexei Starovoitov1be7f752015-10-07 22:23:21 -070033int sysctl_unprivileged_bpf_disabled __read_mostly;
34
Johannes Berg40077e02017-04-11 15:34:58 +020035static const struct bpf_map_ops * const bpf_map_types[] = {
36#define BPF_PROG_TYPE(_id, _ops)
37#define BPF_MAP_TYPE(_id, _ops) \
38 [_id] = &_ops,
39#include <linux/bpf_types.h>
40#undef BPF_PROG_TYPE
41#undef BPF_MAP_TYPE
42};
Alexei Starovoitov99c55f72014-09-26 00:16:57 -070043
44static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
45{
Alexei Starovoitov99c55f72014-09-26 00:16:57 -070046 struct bpf_map *map;
47
Johannes Berg40077e02017-04-11 15:34:58 +020048 if (attr->map_type >= ARRAY_SIZE(bpf_map_types) ||
49 !bpf_map_types[attr->map_type])
50 return ERR_PTR(-EINVAL);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -070051
Johannes Berg40077e02017-04-11 15:34:58 +020052 map = bpf_map_types[attr->map_type]->map_alloc(attr);
53 if (IS_ERR(map))
54 return map;
55 map->ops = bpf_map_types[attr->map_type];
56 map->map_type = attr->map_type;
57 return map;
Alexei Starovoitov99c55f72014-09-26 00:16:57 -070058}
59
Daniel Borkmannd407bd22017-01-18 15:14:17 +010060void *bpf_map_area_alloc(size_t size)
61{
62 /* We definitely need __GFP_NORETRY, so OOM killer doesn't
63 * trigger under memory pressure as we really just want to
64 * fail instead.
65 */
66 const gfp_t flags = __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO;
67 void *area;
68
69 if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) {
70 area = kmalloc(size, GFP_USER | flags);
71 if (area != NULL)
72 return area;
73 }
74
Michal Hocko19809c22017-05-08 15:57:44 -070075 return __vmalloc(size, GFP_KERNEL | flags, PAGE_KERNEL);
Daniel Borkmannd407bd22017-01-18 15:14:17 +010076}
77
78void bpf_map_area_free(void *area)
79{
80 kvfree(area);
81}
82
Alexei Starovoitov6c905982016-03-07 21:57:15 -080083int bpf_map_precharge_memlock(u32 pages)
84{
85 struct user_struct *user = get_current_user();
86 unsigned long memlock_limit, cur;
87
88 memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
89 cur = atomic_long_read(&user->locked_vm);
90 free_uid(user);
91 if (cur + pages > memlock_limit)
92 return -EPERM;
93 return 0;
94}
95
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -070096static int bpf_map_charge_memlock(struct bpf_map *map)
97{
98 struct user_struct *user = get_current_user();
99 unsigned long memlock_limit;
100
101 memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
102
103 atomic_long_add(map->pages, &user->locked_vm);
104
105 if (atomic_long_read(&user->locked_vm) > memlock_limit) {
106 atomic_long_sub(map->pages, &user->locked_vm);
107 free_uid(user);
108 return -EPERM;
109 }
110 map->user = user;
111 return 0;
112}
113
114static void bpf_map_uncharge_memlock(struct bpf_map *map)
115{
116 struct user_struct *user = map->user;
117
118 atomic_long_sub(map->pages, &user->locked_vm);
119 free_uid(user);
120}
121
Martin KaFai Lauf3f1c052017-06-05 12:15:47 -0700122static int bpf_map_alloc_id(struct bpf_map *map)
123{
124 int id;
125
126 spin_lock_bh(&map_idr_lock);
127 id = idr_alloc_cyclic(&map_idr, map, 1, INT_MAX, GFP_ATOMIC);
128 if (id > 0)
129 map->id = id;
130 spin_unlock_bh(&map_idr_lock);
131
132 if (WARN_ON_ONCE(!id))
133 return -ENOSPC;
134
135 return id > 0 ? 0 : id;
136}
137
138static void bpf_map_free_id(struct bpf_map *map)
139{
140 spin_lock_bh(&map_idr_lock);
141 idr_remove(&map_idr, map->id);
142 spin_unlock_bh(&map_idr_lock);
143}
144
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700145/* called from workqueue */
146static void bpf_map_free_deferred(struct work_struct *work)
147{
148 struct bpf_map *map = container_of(work, struct bpf_map, work);
149
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700150 bpf_map_uncharge_memlock(map);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700151 /* implementation dependent freeing */
152 map->ops->map_free(map);
153}
154
Daniel Borkmannc9da1612015-11-24 21:28:15 +0100155static void bpf_map_put_uref(struct bpf_map *map)
156{
157 if (atomic_dec_and_test(&map->usercnt)) {
158 if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY)
159 bpf_fd_array_map_clear(map);
160 }
161}
162
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700163/* decrement map refcnt and schedule it for freeing via workqueue
164 * (unrelying map implementation ops->map_free() might sleep)
165 */
166void bpf_map_put(struct bpf_map *map)
167{
168 if (atomic_dec_and_test(&map->refcnt)) {
Martin KaFai Lau34ad5582017-06-05 12:15:48 -0700169 /* bpf_map_free_id() must be called first */
Martin KaFai Lauf3f1c052017-06-05 12:15:47 -0700170 bpf_map_free_id(map);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700171 INIT_WORK(&map->work, bpf_map_free_deferred);
172 schedule_work(&map->work);
173 }
174}
175
Daniel Borkmannc9da1612015-11-24 21:28:15 +0100176void bpf_map_put_with_uref(struct bpf_map *map)
177{
178 bpf_map_put_uref(map);
179 bpf_map_put(map);
180}
181
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700182static int bpf_map_release(struct inode *inode, struct file *filp)
183{
Daniel Borkmann61d1b6a2016-06-15 22:47:12 +0200184 struct bpf_map *map = filp->private_data;
185
186 if (map->ops->map_release)
187 map->ops->map_release(map, filp);
188
189 bpf_map_put_with_uref(map);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700190 return 0;
191}
192
Daniel Borkmannf99bf202015-11-19 11:56:22 +0100193#ifdef CONFIG_PROC_FS
194static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
195{
196 const struct bpf_map *map = filp->private_data;
Daniel Borkmann21116b72016-11-26 01:28:07 +0100197 const struct bpf_array *array;
198 u32 owner_prog_type = 0;
199
200 if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) {
201 array = container_of(map, struct bpf_array, map);
202 owner_prog_type = array->owner_prog_type;
203 }
Daniel Borkmannf99bf202015-11-19 11:56:22 +0100204
205 seq_printf(m,
206 "map_type:\t%u\n"
207 "key_size:\t%u\n"
208 "value_size:\t%u\n"
Daniel Borkmann322cea22016-03-25 00:30:25 +0100209 "max_entries:\t%u\n"
Daniel Borkmann21116b72016-11-26 01:28:07 +0100210 "map_flags:\t%#x\n"
211 "memlock:\t%llu\n",
Daniel Borkmannf99bf202015-11-19 11:56:22 +0100212 map->map_type,
213 map->key_size,
214 map->value_size,
Daniel Borkmann322cea22016-03-25 00:30:25 +0100215 map->max_entries,
Daniel Borkmann21116b72016-11-26 01:28:07 +0100216 map->map_flags,
217 map->pages * 1ULL << PAGE_SHIFT);
218
219 if (owner_prog_type)
220 seq_printf(m, "owner_prog_type:\t%u\n",
221 owner_prog_type);
Daniel Borkmannf99bf202015-11-19 11:56:22 +0100222}
223#endif
224
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700225static const struct file_operations bpf_map_fops = {
Daniel Borkmannf99bf202015-11-19 11:56:22 +0100226#ifdef CONFIG_PROC_FS
227 .show_fdinfo = bpf_map_show_fdinfo,
228#endif
229 .release = bpf_map_release,
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700230};
231
Daniel Borkmannb2197752015-10-29 14:58:09 +0100232int bpf_map_new_fd(struct bpf_map *map)
Daniel Borkmannaa797812015-10-29 14:58:06 +0100233{
234 return anon_inode_getfd("bpf-map", &bpf_map_fops, map,
235 O_RDWR | O_CLOEXEC);
236}
237
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700238/* helper macro to check that unused fields 'union bpf_attr' are zero */
239#define CHECK_ATTR(CMD) \
240 memchr_inv((void *) &attr->CMD##_LAST_FIELD + \
241 sizeof(attr->CMD##_LAST_FIELD), 0, \
242 sizeof(*attr) - \
243 offsetof(union bpf_attr, CMD##_LAST_FIELD) - \
244 sizeof(attr->CMD##_LAST_FIELD)) != NULL
245
Martin KaFai Lau56f668d2017-03-22 10:00:33 -0700246#define BPF_MAP_CREATE_LAST_FIELD inner_map_fd
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700247/* called via syscall */
248static int map_create(union bpf_attr *attr)
249{
250 struct bpf_map *map;
251 int err;
252
253 err = CHECK_ATTR(BPF_MAP_CREATE);
254 if (err)
255 return -EINVAL;
256
257 /* find map type and init map: hashtable vs rbtree vs bloom vs ... */
258 map = find_and_alloc_map(attr);
259 if (IS_ERR(map))
260 return PTR_ERR(map);
261
262 atomic_set(&map->refcnt, 1);
Daniel Borkmannc9da1612015-11-24 21:28:15 +0100263 atomic_set(&map->usercnt, 1);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700264
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700265 err = bpf_map_charge_memlock(map);
266 if (err)
Daniel Borkmann20b2b242016-11-04 00:56:31 +0100267 goto free_map_nouncharge;
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700268
Martin KaFai Lauf3f1c052017-06-05 12:15:47 -0700269 err = bpf_map_alloc_id(map);
270 if (err)
271 goto free_map;
272
Daniel Borkmannaa797812015-10-29 14:58:06 +0100273 err = bpf_map_new_fd(map);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700274 if (err < 0)
275 /* failed to allocate fd */
Martin KaFai Lauf3f1c052017-06-05 12:15:47 -0700276 goto free_id;
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700277
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100278 trace_bpf_map_create(map, err);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700279 return err;
280
Martin KaFai Lauf3f1c052017-06-05 12:15:47 -0700281free_id:
282 bpf_map_free_id(map);
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700283free_map:
Daniel Borkmann20b2b242016-11-04 00:56:31 +0100284 bpf_map_uncharge_memlock(map);
285free_map_nouncharge:
Alexei Starovoitov99c55f72014-09-26 00:16:57 -0700286 map->ops->map_free(map);
287 return err;
288}
289
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700290/* if error is returned, fd is released.
291 * On success caller should complete fd access with matching fdput()
292 */
Daniel Borkmannc2101292015-10-29 14:58:07 +0100293struct bpf_map *__bpf_map_get(struct fd f)
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700294{
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700295 if (!f.file)
296 return ERR_PTR(-EBADF);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700297 if (f.file->f_op != &bpf_map_fops) {
298 fdput(f);
299 return ERR_PTR(-EINVAL);
300 }
301
Daniel Borkmannc2101292015-10-29 14:58:07 +0100302 return f.file->private_data;
303}
304
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700305/* prog's and map's refcnt limit */
306#define BPF_MAX_REFCNT 32768
307
308struct bpf_map *bpf_map_inc(struct bpf_map *map, bool uref)
Daniel Borkmannc9da1612015-11-24 21:28:15 +0100309{
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700310 if (atomic_inc_return(&map->refcnt) > BPF_MAX_REFCNT) {
311 atomic_dec(&map->refcnt);
312 return ERR_PTR(-EBUSY);
313 }
Daniel Borkmannc9da1612015-11-24 21:28:15 +0100314 if (uref)
315 atomic_inc(&map->usercnt);
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700316 return map;
Daniel Borkmannc9da1612015-11-24 21:28:15 +0100317}
318
319struct bpf_map *bpf_map_get_with_uref(u32 ufd)
Daniel Borkmannc2101292015-10-29 14:58:07 +0100320{
321 struct fd f = fdget(ufd);
322 struct bpf_map *map;
323
324 map = __bpf_map_get(f);
325 if (IS_ERR(map))
326 return map;
327
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700328 map = bpf_map_inc(map, true);
Daniel Borkmannc2101292015-10-29 14:58:07 +0100329 fdput(f);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700330
331 return map;
332}
333
Alexei Starovoitovb8cdc052016-03-09 18:56:49 -0800334int __weak bpf_stackmap_copy(struct bpf_map *map, void *key, void *value)
335{
336 return -ENOTSUPP;
337}
338
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700339/* last field in 'union bpf_attr' used by this command */
340#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD value
341
342static int map_lookup_elem(union bpf_attr *attr)
343{
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100344 void __user *ukey = u64_to_user_ptr(attr->key);
345 void __user *uvalue = u64_to_user_ptr(attr->value);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700346 int ufd = attr->map_fd;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700347 struct bpf_map *map;
Alexei Starovoitov8ebe6672015-01-22 17:11:08 -0800348 void *key, *value, *ptr;
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800349 u32 value_size;
Daniel Borkmann592867b2015-09-08 18:00:09 +0200350 struct fd f;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700351 int err;
352
353 if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM))
354 return -EINVAL;
355
Daniel Borkmann592867b2015-09-08 18:00:09 +0200356 f = fdget(ufd);
Daniel Borkmannc2101292015-10-29 14:58:07 +0100357 map = __bpf_map_get(f);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700358 if (IS_ERR(map))
359 return PTR_ERR(map);
360
361 err = -ENOMEM;
362 key = kmalloc(map->key_size, GFP_USER);
363 if (!key)
364 goto err_put;
365
366 err = -EFAULT;
367 if (copy_from_user(key, ukey, map->key_size) != 0)
368 goto free_key;
369
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800370 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
Martin KaFai Lau8f844932016-11-11 10:55:10 -0800371 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800372 map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
373 value_size = round_up(map->value_size, 8) * num_possible_cpus();
374 else
375 value_size = map->value_size;
376
Alexei Starovoitov8ebe6672015-01-22 17:11:08 -0800377 err = -ENOMEM;
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800378 value = kmalloc(value_size, GFP_USER | __GFP_NOWARN);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700379 if (!value)
Alexei Starovoitov8ebe6672015-01-22 17:11:08 -0800380 goto free_key;
381
Martin KaFai Lau8f844932016-11-11 10:55:10 -0800382 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
383 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800384 err = bpf_percpu_hash_copy(map, key, value);
385 } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
386 err = bpf_percpu_array_copy(map, key, value);
Alexei Starovoitov557c0c62016-03-07 21:57:17 -0800387 } else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
388 err = bpf_stackmap_copy(map, key, value);
Martin KaFai Laubcc6b1b2017-03-22 10:00:34 -0700389 } else if (map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
390 map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
Martin KaFai Lau56f668d2017-03-22 10:00:33 -0700391 err = -ENOTSUPP;
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800392 } else {
393 rcu_read_lock();
394 ptr = map->ops->map_lookup_elem(map, key);
395 if (ptr)
396 memcpy(value, ptr, value_size);
397 rcu_read_unlock();
398 err = ptr ? 0 : -ENOENT;
399 }
Alexei Starovoitov8ebe6672015-01-22 17:11:08 -0800400
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800401 if (err)
Alexei Starovoitov8ebe6672015-01-22 17:11:08 -0800402 goto free_value;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700403
404 err = -EFAULT;
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800405 if (copy_to_user(uvalue, value, value_size) != 0)
Alexei Starovoitov8ebe6672015-01-22 17:11:08 -0800406 goto free_value;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700407
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100408 trace_bpf_map_lookup_elem(map, ufd, key, value);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700409 err = 0;
410
Alexei Starovoitov8ebe6672015-01-22 17:11:08 -0800411free_value:
412 kfree(value);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700413free_key:
414 kfree(key);
415err_put:
416 fdput(f);
417 return err;
418}
419
Alexei Starovoitov3274f522014-11-13 17:36:44 -0800420#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700421
422static int map_update_elem(union bpf_attr *attr)
423{
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100424 void __user *ukey = u64_to_user_ptr(attr->key);
425 void __user *uvalue = u64_to_user_ptr(attr->value);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700426 int ufd = attr->map_fd;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700427 struct bpf_map *map;
428 void *key, *value;
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800429 u32 value_size;
Daniel Borkmann592867b2015-09-08 18:00:09 +0200430 struct fd f;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700431 int err;
432
433 if (CHECK_ATTR(BPF_MAP_UPDATE_ELEM))
434 return -EINVAL;
435
Daniel Borkmann592867b2015-09-08 18:00:09 +0200436 f = fdget(ufd);
Daniel Borkmannc2101292015-10-29 14:58:07 +0100437 map = __bpf_map_get(f);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700438 if (IS_ERR(map))
439 return PTR_ERR(map);
440
441 err = -ENOMEM;
442 key = kmalloc(map->key_size, GFP_USER);
443 if (!key)
444 goto err_put;
445
446 err = -EFAULT;
447 if (copy_from_user(key, ukey, map->key_size) != 0)
448 goto free_key;
449
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800450 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
Martin KaFai Lau8f844932016-11-11 10:55:10 -0800451 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800452 map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
453 value_size = round_up(map->value_size, 8) * num_possible_cpus();
454 else
455 value_size = map->value_size;
456
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700457 err = -ENOMEM;
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800458 value = kmalloc(value_size, GFP_USER | __GFP_NOWARN);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700459 if (!value)
460 goto free_key;
461
462 err = -EFAULT;
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800463 if (copy_from_user(value, uvalue, value_size) != 0)
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700464 goto free_value;
465
Alexei Starovoitovb121d1e2016-03-07 21:57:13 -0800466 /* must increment bpf_prog_active to avoid kprobe+bpf triggering from
467 * inside bpf map update or delete otherwise deadlocks are possible
468 */
469 preempt_disable();
470 __this_cpu_inc(bpf_prog_active);
Martin KaFai Lau8f844932016-11-11 10:55:10 -0800471 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
472 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800473 err = bpf_percpu_hash_update(map, key, value, attr->flags);
474 } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
475 err = bpf_percpu_array_update(map, key, value, attr->flags);
Daniel Borkmannd056a782016-06-15 22:47:13 +0200476 } else if (map->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY ||
Martin KaFai Lau4ed8ec52016-06-30 10:28:43 -0700477 map->map_type == BPF_MAP_TYPE_PROG_ARRAY ||
Martin KaFai Lau56f668d2017-03-22 10:00:33 -0700478 map->map_type == BPF_MAP_TYPE_CGROUP_ARRAY ||
479 map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS) {
Daniel Borkmannd056a782016-06-15 22:47:13 +0200480 rcu_read_lock();
481 err = bpf_fd_array_map_update_elem(map, f.file, key, value,
482 attr->flags);
483 rcu_read_unlock();
Martin KaFai Laubcc6b1b2017-03-22 10:00:34 -0700484 } else if (map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
485 rcu_read_lock();
486 err = bpf_fd_htab_map_update_elem(map, f.file, key, value,
487 attr->flags);
488 rcu_read_unlock();
Alexei Starovoitov15a07b32016-02-01 22:39:55 -0800489 } else {
490 rcu_read_lock();
491 err = map->ops->map_update_elem(map, key, value, attr->flags);
492 rcu_read_unlock();
493 }
Alexei Starovoitovb121d1e2016-03-07 21:57:13 -0800494 __this_cpu_dec(bpf_prog_active);
495 preempt_enable();
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700496
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100497 if (!err)
498 trace_bpf_map_update_elem(map, ufd, key, value);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700499free_value:
500 kfree(value);
501free_key:
502 kfree(key);
503err_put:
504 fdput(f);
505 return err;
506}
507
508#define BPF_MAP_DELETE_ELEM_LAST_FIELD key
509
510static int map_delete_elem(union bpf_attr *attr)
511{
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100512 void __user *ukey = u64_to_user_ptr(attr->key);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700513 int ufd = attr->map_fd;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700514 struct bpf_map *map;
Daniel Borkmann592867b2015-09-08 18:00:09 +0200515 struct fd f;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700516 void *key;
517 int err;
518
519 if (CHECK_ATTR(BPF_MAP_DELETE_ELEM))
520 return -EINVAL;
521
Daniel Borkmann592867b2015-09-08 18:00:09 +0200522 f = fdget(ufd);
Daniel Borkmannc2101292015-10-29 14:58:07 +0100523 map = __bpf_map_get(f);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700524 if (IS_ERR(map))
525 return PTR_ERR(map);
526
527 err = -ENOMEM;
528 key = kmalloc(map->key_size, GFP_USER);
529 if (!key)
530 goto err_put;
531
532 err = -EFAULT;
533 if (copy_from_user(key, ukey, map->key_size) != 0)
534 goto free_key;
535
Alexei Starovoitovb121d1e2016-03-07 21:57:13 -0800536 preempt_disable();
537 __this_cpu_inc(bpf_prog_active);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700538 rcu_read_lock();
539 err = map->ops->map_delete_elem(map, key);
540 rcu_read_unlock();
Alexei Starovoitovb121d1e2016-03-07 21:57:13 -0800541 __this_cpu_dec(bpf_prog_active);
542 preempt_enable();
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700543
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100544 if (!err)
545 trace_bpf_map_delete_elem(map, ufd, key);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700546free_key:
547 kfree(key);
548err_put:
549 fdput(f);
550 return err;
551}
552
553/* last field in 'union bpf_attr' used by this command */
554#define BPF_MAP_GET_NEXT_KEY_LAST_FIELD next_key
555
556static int map_get_next_key(union bpf_attr *attr)
557{
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100558 void __user *ukey = u64_to_user_ptr(attr->key);
559 void __user *unext_key = u64_to_user_ptr(attr->next_key);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700560 int ufd = attr->map_fd;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700561 struct bpf_map *map;
562 void *key, *next_key;
Daniel Borkmann592867b2015-09-08 18:00:09 +0200563 struct fd f;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700564 int err;
565
566 if (CHECK_ATTR(BPF_MAP_GET_NEXT_KEY))
567 return -EINVAL;
568
Daniel Borkmann592867b2015-09-08 18:00:09 +0200569 f = fdget(ufd);
Daniel Borkmannc2101292015-10-29 14:58:07 +0100570 map = __bpf_map_get(f);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700571 if (IS_ERR(map))
572 return PTR_ERR(map);
573
Teng Qin8fe45922017-04-24 19:00:37 -0700574 if (ukey) {
575 err = -ENOMEM;
576 key = kmalloc(map->key_size, GFP_USER);
577 if (!key)
578 goto err_put;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700579
Teng Qin8fe45922017-04-24 19:00:37 -0700580 err = -EFAULT;
581 if (copy_from_user(key, ukey, map->key_size) != 0)
582 goto free_key;
583 } else {
584 key = NULL;
585 }
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700586
587 err = -ENOMEM;
588 next_key = kmalloc(map->key_size, GFP_USER);
589 if (!next_key)
590 goto free_key;
591
592 rcu_read_lock();
593 err = map->ops->map_get_next_key(map, key, next_key);
594 rcu_read_unlock();
595 if (err)
596 goto free_next_key;
597
598 err = -EFAULT;
599 if (copy_to_user(unext_key, next_key, map->key_size) != 0)
600 goto free_next_key;
601
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100602 trace_bpf_map_next_key(map, ufd, key, next_key);
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -0700603 err = 0;
604
605free_next_key:
606 kfree(next_key);
607free_key:
608 kfree(key);
609err_put:
610 fdput(f);
611 return err;
612}
613
Johannes Bergbe9370a2017-04-11 15:34:57 +0200614static const struct bpf_verifier_ops * const bpf_prog_types[] = {
615#define BPF_PROG_TYPE(_id, _ops) \
616 [_id] = &_ops,
Johannes Berg40077e02017-04-11 15:34:58 +0200617#define BPF_MAP_TYPE(_id, _ops)
Johannes Bergbe9370a2017-04-11 15:34:57 +0200618#include <linux/bpf_types.h>
619#undef BPF_PROG_TYPE
Johannes Berg40077e02017-04-11 15:34:58 +0200620#undef BPF_MAP_TYPE
Johannes Bergbe9370a2017-04-11 15:34:57 +0200621};
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700622
623static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
624{
Johannes Bergbe9370a2017-04-11 15:34:57 +0200625 if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type])
626 return -EINVAL;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700627
Johannes Bergbe9370a2017-04-11 15:34:57 +0200628 prog->aux->ops = bpf_prog_types[type];
629 prog->type = type;
630 return 0;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700631}
632
633/* drop refcnt on maps used by eBPF program and free auxilary data */
634static void free_used_maps(struct bpf_prog_aux *aux)
635{
636 int i;
637
638 for (i = 0; i < aux->used_map_cnt; i++)
639 bpf_map_put(aux->used_maps[i]);
640
641 kfree(aux->used_maps);
642}
643
Daniel Borkmann5ccb0712016-12-18 01:52:58 +0100644int __bpf_prog_charge(struct user_struct *user, u32 pages)
645{
646 unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
647 unsigned long user_bufs;
648
649 if (user) {
650 user_bufs = atomic_long_add_return(pages, &user->locked_vm);
651 if (user_bufs > memlock_limit) {
652 atomic_long_sub(pages, &user->locked_vm);
653 return -EPERM;
654 }
655 }
656
657 return 0;
658}
659
660void __bpf_prog_uncharge(struct user_struct *user, u32 pages)
661{
662 if (user)
663 atomic_long_sub(pages, &user->locked_vm);
664}
665
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700666static int bpf_prog_charge_memlock(struct bpf_prog *prog)
667{
668 struct user_struct *user = get_current_user();
Daniel Borkmann5ccb0712016-12-18 01:52:58 +0100669 int ret;
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700670
Daniel Borkmann5ccb0712016-12-18 01:52:58 +0100671 ret = __bpf_prog_charge(user, prog->pages);
672 if (ret) {
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700673 free_uid(user);
Daniel Borkmann5ccb0712016-12-18 01:52:58 +0100674 return ret;
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700675 }
Daniel Borkmann5ccb0712016-12-18 01:52:58 +0100676
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700677 prog->aux->user = user;
678 return 0;
679}
680
681static void bpf_prog_uncharge_memlock(struct bpf_prog *prog)
682{
683 struct user_struct *user = prog->aux->user;
684
Daniel Borkmann5ccb0712016-12-18 01:52:58 +0100685 __bpf_prog_uncharge(user, prog->pages);
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700686 free_uid(user);
687}
688
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700689static int bpf_prog_alloc_id(struct bpf_prog *prog)
690{
691 int id;
692
693 spin_lock_bh(&prog_idr_lock);
694 id = idr_alloc_cyclic(&prog_idr, prog, 1, INT_MAX, GFP_ATOMIC);
695 if (id > 0)
696 prog->aux->id = id;
697 spin_unlock_bh(&prog_idr_lock);
698
699 /* id is in [1, INT_MAX) */
700 if (WARN_ON_ONCE(!id))
701 return -ENOSPC;
702
703 return id > 0 ? 0 : id;
704}
705
706static void bpf_prog_free_id(struct bpf_prog *prog)
707{
708 /* cBPF to eBPF migrations are currently not in the idr store. */
709 if (!prog->aux->id)
710 return;
711
712 spin_lock_bh(&prog_idr_lock);
713 idr_remove(&prog_idr, prog->aux->id);
714 spin_unlock_bh(&prog_idr_lock);
715}
716
Daniel Borkmann1aacde32016-06-30 17:24:43 +0200717static void __bpf_prog_put_rcu(struct rcu_head *rcu)
Alexei Starovoitovabf2e7d2015-05-28 19:26:02 -0700718{
719 struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu);
720
721 free_used_maps(aux);
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700722 bpf_prog_uncharge_memlock(aux->prog);
Alexei Starovoitovabf2e7d2015-05-28 19:26:02 -0700723 bpf_prog_free(aux->prog);
724}
725
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700726void bpf_prog_put(struct bpf_prog *prog)
727{
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100728 if (atomic_dec_and_test(&prog->aux->refcnt)) {
729 trace_bpf_prog_put_rcu(prog);
Martin KaFai Lau34ad5582017-06-05 12:15:48 -0700730 /* bpf_prog_free_id() must be called first */
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700731 bpf_prog_free_id(prog);
Daniel Borkmann74451e662017-02-16 22:24:50 +0100732 bpf_prog_kallsyms_del(prog);
Daniel Borkmann1aacde32016-06-30 17:24:43 +0200733 call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu);
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100734 }
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700735}
Daniel Borkmanne2e9b652015-03-01 12:31:48 +0100736EXPORT_SYMBOL_GPL(bpf_prog_put);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700737
738static int bpf_prog_release(struct inode *inode, struct file *filp)
739{
740 struct bpf_prog *prog = filp->private_data;
741
Daniel Borkmann1aacde32016-06-30 17:24:43 +0200742 bpf_prog_put(prog);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700743 return 0;
744}
745
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100746#ifdef CONFIG_PROC_FS
747static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
748{
749 const struct bpf_prog *prog = filp->private_data;
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100750 char prog_tag[sizeof(prog->tag) * 2 + 1] = { };
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100751
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100752 bin2hex(prog_tag, prog->tag, sizeof(prog->tag));
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100753 seq_printf(m,
754 "prog_type:\t%u\n"
755 "prog_jited:\t%u\n"
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100756 "prog_tag:\t%s\n"
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100757 "memlock:\t%llu\n",
758 prog->type,
759 prog->jited,
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100760 prog_tag,
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100761 prog->pages * 1ULL << PAGE_SHIFT);
762}
763#endif
764
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700765static const struct file_operations bpf_prog_fops = {
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100766#ifdef CONFIG_PROC_FS
767 .show_fdinfo = bpf_prog_show_fdinfo,
768#endif
769 .release = bpf_prog_release,
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700770};
771
Daniel Borkmannb2197752015-10-29 14:58:09 +0100772int bpf_prog_new_fd(struct bpf_prog *prog)
Daniel Borkmannaa797812015-10-29 14:58:06 +0100773{
774 return anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog,
775 O_RDWR | O_CLOEXEC);
776}
777
Daniel Borkmann113214b2016-06-30 17:24:44 +0200778static struct bpf_prog *____bpf_prog_get(struct fd f)
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700779{
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700780 if (!f.file)
781 return ERR_PTR(-EBADF);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700782 if (f.file->f_op != &bpf_prog_fops) {
783 fdput(f);
784 return ERR_PTR(-EINVAL);
785 }
786
Daniel Borkmannc2101292015-10-29 14:58:07 +0100787 return f.file->private_data;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700788}
789
Brenden Blanco59d36562016-07-19 12:16:46 -0700790struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i)
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700791{
Brenden Blanco59d36562016-07-19 12:16:46 -0700792 if (atomic_add_return(i, &prog->aux->refcnt) > BPF_MAX_REFCNT) {
793 atomic_sub(i, &prog->aux->refcnt);
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700794 return ERR_PTR(-EBUSY);
795 }
796 return prog;
797}
Brenden Blanco59d36562016-07-19 12:16:46 -0700798EXPORT_SYMBOL_GPL(bpf_prog_add);
799
Daniel Borkmannc5405942016-11-09 22:02:34 +0100800void bpf_prog_sub(struct bpf_prog *prog, int i)
801{
802 /* Only to be used for undoing previous bpf_prog_add() in some
803 * error path. We still know that another entity in our call
804 * path holds a reference to the program, thus atomic_sub() can
805 * be safely used in such cases!
806 */
807 WARN_ON(atomic_sub_return(i, &prog->aux->refcnt) == 0);
808}
809EXPORT_SYMBOL_GPL(bpf_prog_sub);
810
Brenden Blanco59d36562016-07-19 12:16:46 -0700811struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
812{
813 return bpf_prog_add(prog, 1);
814}
Daniel Borkmann97bc4022016-11-19 01:45:00 +0100815EXPORT_SYMBOL_GPL(bpf_prog_inc);
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700816
Daniel Borkmann113214b2016-06-30 17:24:44 +0200817static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type)
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700818{
819 struct fd f = fdget(ufd);
820 struct bpf_prog *prog;
821
Daniel Borkmann113214b2016-06-30 17:24:44 +0200822 prog = ____bpf_prog_get(f);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700823 if (IS_ERR(prog))
824 return prog;
Daniel Borkmann113214b2016-06-30 17:24:44 +0200825 if (type && prog->type != *type) {
826 prog = ERR_PTR(-EINVAL);
827 goto out;
828 }
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700829
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700830 prog = bpf_prog_inc(prog);
Daniel Borkmann113214b2016-06-30 17:24:44 +0200831out:
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700832 fdput(f);
833 return prog;
834}
Daniel Borkmann113214b2016-06-30 17:24:44 +0200835
836struct bpf_prog *bpf_prog_get(u32 ufd)
837{
838 return __bpf_prog_get(ufd, NULL);
839}
840
841struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
842{
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100843 struct bpf_prog *prog = __bpf_prog_get(ufd, &type);
844
845 if (!IS_ERR(prog))
846 trace_bpf_prog_get_type(prog);
847 return prog;
Daniel Borkmann113214b2016-06-30 17:24:44 +0200848}
849EXPORT_SYMBOL_GPL(bpf_prog_get_type);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700850
851/* last field in 'union bpf_attr' used by this command */
David S. Millere07b98d2017-05-10 11:38:07 -0700852#define BPF_PROG_LOAD_LAST_FIELD prog_flags
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700853
854static int bpf_prog_load(union bpf_attr *attr)
855{
856 enum bpf_prog_type type = attr->prog_type;
857 struct bpf_prog *prog;
858 int err;
859 char license[128];
860 bool is_gpl;
861
862 if (CHECK_ATTR(BPF_PROG_LOAD))
863 return -EINVAL;
864
David S. Millere07b98d2017-05-10 11:38:07 -0700865 if (attr->prog_flags & ~BPF_F_STRICT_ALIGNMENT)
866 return -EINVAL;
867
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700868 /* copy eBPF program license from user space */
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100869 if (strncpy_from_user(license, u64_to_user_ptr(attr->license),
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700870 sizeof(license) - 1) < 0)
871 return -EFAULT;
872 license[sizeof(license) - 1] = 0;
873
874 /* eBPF programs must be GPL compatible to use GPL-ed functions */
875 is_gpl = license_is_gpl_compatible(license);
876
Daniel Borkmannef0915c2016-12-07 01:15:44 +0100877 if (attr->insn_cnt == 0 || attr->insn_cnt > BPF_MAXINSNS)
878 return -E2BIG;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700879
Alexei Starovoitov25415172015-03-25 12:49:20 -0700880 if (type == BPF_PROG_TYPE_KPROBE &&
881 attr->kern_version != LINUX_VERSION_CODE)
882 return -EINVAL;
883
Chenbo Feng80b7d812017-05-31 18:16:00 -0700884 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
885 type != BPF_PROG_TYPE_CGROUP_SKB &&
886 !capable(CAP_SYS_ADMIN))
Alexei Starovoitov1be7f752015-10-07 22:23:21 -0700887 return -EPERM;
888
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700889 /* plain bpf_prog allocation */
890 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
891 if (!prog)
892 return -ENOMEM;
893
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700894 err = bpf_prog_charge_memlock(prog);
895 if (err)
896 goto free_prog_nouncharge;
897
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700898 prog->len = attr->insn_cnt;
899
900 err = -EFAULT;
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100901 if (copy_from_user(prog->insns, u64_to_user_ptr(attr->insns),
Daniel Borkmannaafe6ae2016-12-18 01:52:57 +0100902 bpf_prog_insn_size(prog)) != 0)
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700903 goto free_prog;
904
905 prog->orig_prog = NULL;
Daniel Borkmanna91263d2015-09-30 01:41:50 +0200906 prog->jited = 0;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700907
908 atomic_set(&prog->aux->refcnt, 1);
Daniel Borkmanna91263d2015-09-30 01:41:50 +0200909 prog->gpl_compatible = is_gpl ? 1 : 0;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700910
911 /* find program type: socket_filter vs tracing_filter */
912 err = find_prog_type(type, prog);
913 if (err < 0)
914 goto free_prog;
915
916 /* run eBPF verifier */
Alexei Starovoitov9bac3d62015-03-13 11:57:42 -0700917 err = bpf_check(&prog, attr);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700918 if (err < 0)
919 goto free_used_maps;
920
921 /* eBPF program is ready to be JITed */
Daniel Borkmannd1c55ab2016-05-13 19:08:31 +0200922 prog = bpf_prog_select_runtime(prog, &err);
Alexei Starovoitov04fd61ab2015-05-19 16:59:03 -0700923 if (err < 0)
924 goto free_used_maps;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700925
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700926 err = bpf_prog_alloc_id(prog);
927 if (err)
928 goto free_used_maps;
929
Daniel Borkmannaa797812015-10-29 14:58:06 +0100930 err = bpf_prog_new_fd(prog);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700931 if (err < 0)
932 /* failed to allocate fd */
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700933 goto free_id;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700934
Daniel Borkmann74451e662017-02-16 22:24:50 +0100935 bpf_prog_kallsyms_add(prog);
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100936 trace_bpf_prog_load(prog, err);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700937 return err;
938
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700939free_id:
940 bpf_prog_free_id(prog);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700941free_used_maps:
942 free_used_maps(prog->aux);
943free_prog:
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700944 bpf_prog_uncharge_memlock(prog);
945free_prog_nouncharge:
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700946 bpf_prog_free(prog);
947 return err;
948}
949
Daniel Borkmannb2197752015-10-29 14:58:09 +0100950#define BPF_OBJ_LAST_FIELD bpf_fd
951
952static int bpf_obj_pin(const union bpf_attr *attr)
953{
954 if (CHECK_ATTR(BPF_OBJ))
955 return -EINVAL;
956
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100957 return bpf_obj_pin_user(attr->bpf_fd, u64_to_user_ptr(attr->pathname));
Daniel Borkmannb2197752015-10-29 14:58:09 +0100958}
959
960static int bpf_obj_get(const union bpf_attr *attr)
961{
962 if (CHECK_ATTR(BPF_OBJ) || attr->bpf_fd != 0)
963 return -EINVAL;
964
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100965 return bpf_obj_get_user(u64_to_user_ptr(attr->pathname));
Daniel Borkmannb2197752015-10-29 14:58:09 +0100966}
967
Daniel Mackf4324552016-11-23 16:52:27 +0100968#ifdef CONFIG_CGROUP_BPF
969
Alexei Starovoitov7f677632017-02-10 20:28:24 -0800970#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
Daniel Mackf4324552016-11-23 16:52:27 +0100971
972static int bpf_prog_attach(const union bpf_attr *attr)
973{
Alexei Starovoitov7f677632017-02-10 20:28:24 -0800974 enum bpf_prog_type ptype;
Daniel Mackf4324552016-11-23 16:52:27 +0100975 struct bpf_prog *prog;
976 struct cgroup *cgrp;
Alexei Starovoitov7f677632017-02-10 20:28:24 -0800977 int ret;
Daniel Mackf4324552016-11-23 16:52:27 +0100978
979 if (!capable(CAP_NET_ADMIN))
980 return -EPERM;
981
982 if (CHECK_ATTR(BPF_PROG_ATTACH))
983 return -EINVAL;
984
Alexei Starovoitov7f677632017-02-10 20:28:24 -0800985 if (attr->attach_flags & ~BPF_F_ALLOW_OVERRIDE)
986 return -EINVAL;
987
Daniel Mackf4324552016-11-23 16:52:27 +0100988 switch (attr->attach_type) {
989 case BPF_CGROUP_INET_INGRESS:
990 case BPF_CGROUP_INET_EGRESS:
David Ahernb2cd1252016-12-01 08:48:03 -0800991 ptype = BPF_PROG_TYPE_CGROUP_SKB;
Daniel Mackf4324552016-11-23 16:52:27 +0100992 break;
David Ahern610236582016-12-01 08:48:04 -0800993 case BPF_CGROUP_INET_SOCK_CREATE:
994 ptype = BPF_PROG_TYPE_CGROUP_SOCK;
995 break;
Daniel Mackf4324552016-11-23 16:52:27 +0100996 default:
997 return -EINVAL;
998 }
999
David Ahernb2cd1252016-12-01 08:48:03 -08001000 prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
1001 if (IS_ERR(prog))
1002 return PTR_ERR(prog);
1003
1004 cgrp = cgroup_get_from_fd(attr->target_fd);
1005 if (IS_ERR(cgrp)) {
1006 bpf_prog_put(prog);
1007 return PTR_ERR(cgrp);
1008 }
1009
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001010 ret = cgroup_bpf_update(cgrp, prog, attr->attach_type,
1011 attr->attach_flags & BPF_F_ALLOW_OVERRIDE);
1012 if (ret)
1013 bpf_prog_put(prog);
David Ahernb2cd1252016-12-01 08:48:03 -08001014 cgroup_put(cgrp);
1015
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001016 return ret;
Daniel Mackf4324552016-11-23 16:52:27 +01001017}
1018
1019#define BPF_PROG_DETACH_LAST_FIELD attach_type
1020
1021static int bpf_prog_detach(const union bpf_attr *attr)
1022{
1023 struct cgroup *cgrp;
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001024 int ret;
Daniel Mackf4324552016-11-23 16:52:27 +01001025
1026 if (!capable(CAP_NET_ADMIN))
1027 return -EPERM;
1028
1029 if (CHECK_ATTR(BPF_PROG_DETACH))
1030 return -EINVAL;
1031
1032 switch (attr->attach_type) {
1033 case BPF_CGROUP_INET_INGRESS:
1034 case BPF_CGROUP_INET_EGRESS:
David Ahern610236582016-12-01 08:48:04 -08001035 case BPF_CGROUP_INET_SOCK_CREATE:
Daniel Mackf4324552016-11-23 16:52:27 +01001036 cgrp = cgroup_get_from_fd(attr->target_fd);
1037 if (IS_ERR(cgrp))
1038 return PTR_ERR(cgrp);
1039
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001040 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
Daniel Mackf4324552016-11-23 16:52:27 +01001041 cgroup_put(cgrp);
1042 break;
1043
1044 default:
1045 return -EINVAL;
1046 }
1047
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001048 return ret;
Daniel Mackf4324552016-11-23 16:52:27 +01001049}
1050#endif /* CONFIG_CGROUP_BPF */
1051
Alexei Starovoitov1cf1cae2017-03-30 21:45:38 -07001052#define BPF_PROG_TEST_RUN_LAST_FIELD test.duration
1053
1054static int bpf_prog_test_run(const union bpf_attr *attr,
1055 union bpf_attr __user *uattr)
1056{
1057 struct bpf_prog *prog;
1058 int ret = -ENOTSUPP;
1059
1060 if (CHECK_ATTR(BPF_PROG_TEST_RUN))
1061 return -EINVAL;
1062
1063 prog = bpf_prog_get(attr->test.prog_fd);
1064 if (IS_ERR(prog))
1065 return PTR_ERR(prog);
1066
1067 if (prog->aux->ops->test_run)
1068 ret = prog->aux->ops->test_run(prog, attr, uattr);
1069
1070 bpf_prog_put(prog);
1071 return ret;
1072}
1073
Martin KaFai Lau34ad5582017-06-05 12:15:48 -07001074#define BPF_OBJ_GET_NEXT_ID_LAST_FIELD next_id
1075
1076static int bpf_obj_get_next_id(const union bpf_attr *attr,
1077 union bpf_attr __user *uattr,
1078 struct idr *idr,
1079 spinlock_t *lock)
1080{
1081 u32 next_id = attr->start_id;
1082 int err = 0;
1083
1084 if (CHECK_ATTR(BPF_OBJ_GET_NEXT_ID) || next_id >= INT_MAX)
1085 return -EINVAL;
1086
1087 if (!capable(CAP_SYS_ADMIN))
1088 return -EPERM;
1089
1090 next_id++;
1091 spin_lock_bh(lock);
1092 if (!idr_get_next(idr, &next_id))
1093 err = -ENOENT;
1094 spin_unlock_bh(lock);
1095
1096 if (!err)
1097 err = put_user(next_id, &uattr->next_id);
1098
1099 return err;
1100}
1101
Alexei Starovoitov99c55f72014-09-26 00:16:57 -07001102SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
1103{
1104 union bpf_attr attr = {};
1105 int err;
1106
Alexei Starovoitov1be7f752015-10-07 22:23:21 -07001107 if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
Alexei Starovoitov99c55f72014-09-26 00:16:57 -07001108 return -EPERM;
1109
1110 if (!access_ok(VERIFY_READ, uattr, 1))
1111 return -EFAULT;
1112
1113 if (size > PAGE_SIZE) /* silly large */
1114 return -E2BIG;
1115
1116 /* If we're handed a bigger struct than we know of,
1117 * ensure all the unknown bits are 0 - i.e. new
1118 * user-space does not rely on any kernel feature
1119 * extensions we dont know about yet.
1120 */
1121 if (size > sizeof(attr)) {
1122 unsigned char __user *addr;
1123 unsigned char __user *end;
1124 unsigned char val;
1125
1126 addr = (void __user *)uattr + sizeof(attr);
1127 end = (void __user *)uattr + size;
1128
1129 for (; addr < end; addr++) {
1130 err = get_user(val, addr);
1131 if (err)
1132 return err;
1133 if (val)
1134 return -E2BIG;
1135 }
1136 size = sizeof(attr);
1137 }
1138
1139 /* copy attributes from user space, may be less than sizeof(bpf_attr) */
1140 if (copy_from_user(&attr, uattr, size) != 0)
1141 return -EFAULT;
1142
1143 switch (cmd) {
1144 case BPF_MAP_CREATE:
1145 err = map_create(&attr);
1146 break;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -07001147 case BPF_MAP_LOOKUP_ELEM:
1148 err = map_lookup_elem(&attr);
1149 break;
1150 case BPF_MAP_UPDATE_ELEM:
1151 err = map_update_elem(&attr);
1152 break;
1153 case BPF_MAP_DELETE_ELEM:
1154 err = map_delete_elem(&attr);
1155 break;
1156 case BPF_MAP_GET_NEXT_KEY:
1157 err = map_get_next_key(&attr);
1158 break;
Alexei Starovoitov09756af2014-09-26 00:17:00 -07001159 case BPF_PROG_LOAD:
1160 err = bpf_prog_load(&attr);
1161 break;
Daniel Borkmannb2197752015-10-29 14:58:09 +01001162 case BPF_OBJ_PIN:
1163 err = bpf_obj_pin(&attr);
1164 break;
1165 case BPF_OBJ_GET:
1166 err = bpf_obj_get(&attr);
1167 break;
Daniel Mackf4324552016-11-23 16:52:27 +01001168#ifdef CONFIG_CGROUP_BPF
1169 case BPF_PROG_ATTACH:
1170 err = bpf_prog_attach(&attr);
1171 break;
1172 case BPF_PROG_DETACH:
1173 err = bpf_prog_detach(&attr);
1174 break;
1175#endif
Alexei Starovoitov1cf1cae2017-03-30 21:45:38 -07001176 case BPF_PROG_TEST_RUN:
1177 err = bpf_prog_test_run(&attr, uattr);
1178 break;
Martin KaFai Lau34ad5582017-06-05 12:15:48 -07001179 case BPF_PROG_GET_NEXT_ID:
1180 err = bpf_obj_get_next_id(&attr, uattr,
1181 &prog_idr, &prog_idr_lock);
1182 break;
1183 case BPF_MAP_GET_NEXT_ID:
1184 err = bpf_obj_get_next_id(&attr, uattr,
1185 &map_idr, &map_idr_lock);
1186 break;
Alexei Starovoitov99c55f72014-09-26 00:16:57 -07001187 default:
1188 err = -EINVAL;
1189 break;
1190 }
1191
1192 return err;
1193}