blob: dc6253bb8ebbbdb6ba5f331a747a9739ef2bbb3d [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
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700706static void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock)
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700707{
708 /* cBPF to eBPF migrations are currently not in the idr store. */
709 if (!prog->aux->id)
710 return;
711
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700712 if (do_idr_lock)
713 spin_lock_bh(&prog_idr_lock);
714 else
715 __acquire(&prog_idr_lock);
716
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700717 idr_remove(&prog_idr, prog->aux->id);
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700718
719 if (do_idr_lock)
720 spin_unlock_bh(&prog_idr_lock);
721 else
722 __release(&prog_idr_lock);
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700723}
724
Daniel Borkmann1aacde32016-06-30 17:24:43 +0200725static void __bpf_prog_put_rcu(struct rcu_head *rcu)
Alexei Starovoitovabf2e7d2015-05-28 19:26:02 -0700726{
727 struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu);
728
729 free_used_maps(aux);
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700730 bpf_prog_uncharge_memlock(aux->prog);
Alexei Starovoitovabf2e7d2015-05-28 19:26:02 -0700731 bpf_prog_free(aux->prog);
732}
733
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700734static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock)
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700735{
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100736 if (atomic_dec_and_test(&prog->aux->refcnt)) {
737 trace_bpf_prog_put_rcu(prog);
Martin KaFai Lau34ad5582017-06-05 12:15:48 -0700738 /* bpf_prog_free_id() must be called first */
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700739 bpf_prog_free_id(prog, do_idr_lock);
Daniel Borkmann74451e662017-02-16 22:24:50 +0100740 bpf_prog_kallsyms_del(prog);
Daniel Borkmann1aacde32016-06-30 17:24:43 +0200741 call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu);
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100742 }
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700743}
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700744
745void bpf_prog_put(struct bpf_prog *prog)
746{
747 __bpf_prog_put(prog, true);
748}
Daniel Borkmanne2e9b652015-03-01 12:31:48 +0100749EXPORT_SYMBOL_GPL(bpf_prog_put);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700750
751static int bpf_prog_release(struct inode *inode, struct file *filp)
752{
753 struct bpf_prog *prog = filp->private_data;
754
Daniel Borkmann1aacde32016-06-30 17:24:43 +0200755 bpf_prog_put(prog);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700756 return 0;
757}
758
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100759#ifdef CONFIG_PROC_FS
760static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
761{
762 const struct bpf_prog *prog = filp->private_data;
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100763 char prog_tag[sizeof(prog->tag) * 2 + 1] = { };
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100764
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100765 bin2hex(prog_tag, prog->tag, sizeof(prog->tag));
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100766 seq_printf(m,
767 "prog_type:\t%u\n"
768 "prog_jited:\t%u\n"
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100769 "prog_tag:\t%s\n"
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100770 "memlock:\t%llu\n",
771 prog->type,
772 prog->jited,
Daniel Borkmannf1f77142017-01-13 23:38:15 +0100773 prog_tag,
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100774 prog->pages * 1ULL << PAGE_SHIFT);
775}
776#endif
777
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700778static const struct file_operations bpf_prog_fops = {
Daniel Borkmann7bd509e2016-12-04 23:19:41 +0100779#ifdef CONFIG_PROC_FS
780 .show_fdinfo = bpf_prog_show_fdinfo,
781#endif
782 .release = bpf_prog_release,
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700783};
784
Daniel Borkmannb2197752015-10-29 14:58:09 +0100785int bpf_prog_new_fd(struct bpf_prog *prog)
Daniel Borkmannaa797812015-10-29 14:58:06 +0100786{
787 return anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog,
788 O_RDWR | O_CLOEXEC);
789}
790
Daniel Borkmann113214b2016-06-30 17:24:44 +0200791static struct bpf_prog *____bpf_prog_get(struct fd f)
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700792{
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700793 if (!f.file)
794 return ERR_PTR(-EBADF);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700795 if (f.file->f_op != &bpf_prog_fops) {
796 fdput(f);
797 return ERR_PTR(-EINVAL);
798 }
799
Daniel Borkmannc2101292015-10-29 14:58:07 +0100800 return f.file->private_data;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700801}
802
Brenden Blanco59d36562016-07-19 12:16:46 -0700803struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i)
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700804{
Brenden Blanco59d36562016-07-19 12:16:46 -0700805 if (atomic_add_return(i, &prog->aux->refcnt) > BPF_MAX_REFCNT) {
806 atomic_sub(i, &prog->aux->refcnt);
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700807 return ERR_PTR(-EBUSY);
808 }
809 return prog;
810}
Brenden Blanco59d36562016-07-19 12:16:46 -0700811EXPORT_SYMBOL_GPL(bpf_prog_add);
812
Daniel Borkmannc5405942016-11-09 22:02:34 +0100813void bpf_prog_sub(struct bpf_prog *prog, int i)
814{
815 /* Only to be used for undoing previous bpf_prog_add() in some
816 * error path. We still know that another entity in our call
817 * path holds a reference to the program, thus atomic_sub() can
818 * be safely used in such cases!
819 */
820 WARN_ON(atomic_sub_return(i, &prog->aux->refcnt) == 0);
821}
822EXPORT_SYMBOL_GPL(bpf_prog_sub);
823
Brenden Blanco59d36562016-07-19 12:16:46 -0700824struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
825{
826 return bpf_prog_add(prog, 1);
827}
Daniel Borkmann97bc4022016-11-19 01:45:00 +0100828EXPORT_SYMBOL_GPL(bpf_prog_inc);
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700829
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700830/* prog_idr_lock should have been held */
831static struct bpf_prog *bpf_prog_inc_not_zero(struct bpf_prog *prog)
832{
833 int refold;
834
835 refold = __atomic_add_unless(&prog->aux->refcnt, 1, 0);
836
837 if (refold >= BPF_MAX_REFCNT) {
838 __bpf_prog_put(prog, false);
839 return ERR_PTR(-EBUSY);
840 }
841
842 if (!refold)
843 return ERR_PTR(-ENOENT);
844
845 return prog;
846}
847
Daniel Borkmann113214b2016-06-30 17:24:44 +0200848static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type)
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700849{
850 struct fd f = fdget(ufd);
851 struct bpf_prog *prog;
852
Daniel Borkmann113214b2016-06-30 17:24:44 +0200853 prog = ____bpf_prog_get(f);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700854 if (IS_ERR(prog))
855 return prog;
Daniel Borkmann113214b2016-06-30 17:24:44 +0200856 if (type && prog->type != *type) {
857 prog = ERR_PTR(-EINVAL);
858 goto out;
859 }
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700860
Alexei Starovoitov92117d82016-04-27 18:56:20 -0700861 prog = bpf_prog_inc(prog);
Daniel Borkmann113214b2016-06-30 17:24:44 +0200862out:
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700863 fdput(f);
864 return prog;
865}
Daniel Borkmann113214b2016-06-30 17:24:44 +0200866
867struct bpf_prog *bpf_prog_get(u32 ufd)
868{
869 return __bpf_prog_get(ufd, NULL);
870}
871
872struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
873{
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100874 struct bpf_prog *prog = __bpf_prog_get(ufd, &type);
875
876 if (!IS_ERR(prog))
877 trace_bpf_prog_get_type(prog);
878 return prog;
Daniel Borkmann113214b2016-06-30 17:24:44 +0200879}
880EXPORT_SYMBOL_GPL(bpf_prog_get_type);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700881
882/* last field in 'union bpf_attr' used by this command */
David S. Millere07b98d2017-05-10 11:38:07 -0700883#define BPF_PROG_LOAD_LAST_FIELD prog_flags
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700884
885static int bpf_prog_load(union bpf_attr *attr)
886{
887 enum bpf_prog_type type = attr->prog_type;
888 struct bpf_prog *prog;
889 int err;
890 char license[128];
891 bool is_gpl;
892
893 if (CHECK_ATTR(BPF_PROG_LOAD))
894 return -EINVAL;
895
David S. Millere07b98d2017-05-10 11:38:07 -0700896 if (attr->prog_flags & ~BPF_F_STRICT_ALIGNMENT)
897 return -EINVAL;
898
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700899 /* copy eBPF program license from user space */
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100900 if (strncpy_from_user(license, u64_to_user_ptr(attr->license),
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700901 sizeof(license) - 1) < 0)
902 return -EFAULT;
903 license[sizeof(license) - 1] = 0;
904
905 /* eBPF programs must be GPL compatible to use GPL-ed functions */
906 is_gpl = license_is_gpl_compatible(license);
907
Daniel Borkmannef0915c2016-12-07 01:15:44 +0100908 if (attr->insn_cnt == 0 || attr->insn_cnt > BPF_MAXINSNS)
909 return -E2BIG;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700910
Alexei Starovoitov25415172015-03-25 12:49:20 -0700911 if (type == BPF_PROG_TYPE_KPROBE &&
912 attr->kern_version != LINUX_VERSION_CODE)
913 return -EINVAL;
914
Chenbo Feng80b7d812017-05-31 18:16:00 -0700915 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
916 type != BPF_PROG_TYPE_CGROUP_SKB &&
917 !capable(CAP_SYS_ADMIN))
Alexei Starovoitov1be7f752015-10-07 22:23:21 -0700918 return -EPERM;
919
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700920 /* plain bpf_prog allocation */
921 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
922 if (!prog)
923 return -ENOMEM;
924
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700925 err = bpf_prog_charge_memlock(prog);
926 if (err)
927 goto free_prog_nouncharge;
928
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700929 prog->len = attr->insn_cnt;
930
931 err = -EFAULT;
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100932 if (copy_from_user(prog->insns, u64_to_user_ptr(attr->insns),
Daniel Borkmannaafe6ae2016-12-18 01:52:57 +0100933 bpf_prog_insn_size(prog)) != 0)
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700934 goto free_prog;
935
936 prog->orig_prog = NULL;
Daniel Borkmanna91263d2015-09-30 01:41:50 +0200937 prog->jited = 0;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700938
939 atomic_set(&prog->aux->refcnt, 1);
Daniel Borkmanna91263d2015-09-30 01:41:50 +0200940 prog->gpl_compatible = is_gpl ? 1 : 0;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700941
942 /* find program type: socket_filter vs tracing_filter */
943 err = find_prog_type(type, prog);
944 if (err < 0)
945 goto free_prog;
946
947 /* run eBPF verifier */
Alexei Starovoitov9bac3d62015-03-13 11:57:42 -0700948 err = bpf_check(&prog, attr);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700949 if (err < 0)
950 goto free_used_maps;
951
952 /* eBPF program is ready to be JITed */
Daniel Borkmannd1c55ab2016-05-13 19:08:31 +0200953 prog = bpf_prog_select_runtime(prog, &err);
Alexei Starovoitov04fd61ab2015-05-19 16:59:03 -0700954 if (err < 0)
955 goto free_used_maps;
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700956
Martin KaFai Laudc4bb0e2017-06-05 12:15:46 -0700957 err = bpf_prog_alloc_id(prog);
958 if (err)
959 goto free_used_maps;
960
Daniel Borkmannaa797812015-10-29 14:58:06 +0100961 err = bpf_prog_new_fd(prog);
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -0700962 if (err < 0) {
963 /* failed to allocate fd.
964 * bpf_prog_put() is needed because the above
965 * bpf_prog_alloc_id() has published the prog
966 * to the userspace and the userspace may
967 * have refcnt-ed it through BPF_PROG_GET_FD_BY_ID.
968 */
969 bpf_prog_put(prog);
970 return err;
971 }
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700972
Daniel Borkmann74451e662017-02-16 22:24:50 +0100973 bpf_prog_kallsyms_add(prog);
Daniel Borkmanna67edbf2017-01-25 02:28:18 +0100974 trace_bpf_prog_load(prog, err);
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700975 return err;
976
977free_used_maps:
978 free_used_maps(prog->aux);
979free_prog:
Alexei Starovoitovaaac3ba2015-10-07 22:23:22 -0700980 bpf_prog_uncharge_memlock(prog);
981free_prog_nouncharge:
Alexei Starovoitov09756af2014-09-26 00:17:00 -0700982 bpf_prog_free(prog);
983 return err;
984}
985
Daniel Borkmannb2197752015-10-29 14:58:09 +0100986#define BPF_OBJ_LAST_FIELD bpf_fd
987
988static int bpf_obj_pin(const union bpf_attr *attr)
989{
990 if (CHECK_ATTR(BPF_OBJ))
991 return -EINVAL;
992
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +0100993 return bpf_obj_pin_user(attr->bpf_fd, u64_to_user_ptr(attr->pathname));
Daniel Borkmannb2197752015-10-29 14:58:09 +0100994}
995
996static int bpf_obj_get(const union bpf_attr *attr)
997{
998 if (CHECK_ATTR(BPF_OBJ) || attr->bpf_fd != 0)
999 return -EINVAL;
1000
Mickaël Salaün535e7b4b2016-11-13 19:44:03 +01001001 return bpf_obj_get_user(u64_to_user_ptr(attr->pathname));
Daniel Borkmannb2197752015-10-29 14:58:09 +01001002}
1003
Daniel Mackf4324552016-11-23 16:52:27 +01001004#ifdef CONFIG_CGROUP_BPF
1005
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001006#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
Daniel Mackf4324552016-11-23 16:52:27 +01001007
1008static int bpf_prog_attach(const union bpf_attr *attr)
1009{
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001010 enum bpf_prog_type ptype;
Daniel Mackf4324552016-11-23 16:52:27 +01001011 struct bpf_prog *prog;
1012 struct cgroup *cgrp;
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001013 int ret;
Daniel Mackf4324552016-11-23 16:52:27 +01001014
1015 if (!capable(CAP_NET_ADMIN))
1016 return -EPERM;
1017
1018 if (CHECK_ATTR(BPF_PROG_ATTACH))
1019 return -EINVAL;
1020
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001021 if (attr->attach_flags & ~BPF_F_ALLOW_OVERRIDE)
1022 return -EINVAL;
1023
Daniel Mackf4324552016-11-23 16:52:27 +01001024 switch (attr->attach_type) {
1025 case BPF_CGROUP_INET_INGRESS:
1026 case BPF_CGROUP_INET_EGRESS:
David Ahernb2cd1252016-12-01 08:48:03 -08001027 ptype = BPF_PROG_TYPE_CGROUP_SKB;
Daniel Mackf4324552016-11-23 16:52:27 +01001028 break;
David Ahern610236582016-12-01 08:48:04 -08001029 case BPF_CGROUP_INET_SOCK_CREATE:
1030 ptype = BPF_PROG_TYPE_CGROUP_SOCK;
1031 break;
Daniel Mackf4324552016-11-23 16:52:27 +01001032 default:
1033 return -EINVAL;
1034 }
1035
David Ahernb2cd1252016-12-01 08:48:03 -08001036 prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
1037 if (IS_ERR(prog))
1038 return PTR_ERR(prog);
1039
1040 cgrp = cgroup_get_from_fd(attr->target_fd);
1041 if (IS_ERR(cgrp)) {
1042 bpf_prog_put(prog);
1043 return PTR_ERR(cgrp);
1044 }
1045
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001046 ret = cgroup_bpf_update(cgrp, prog, attr->attach_type,
1047 attr->attach_flags & BPF_F_ALLOW_OVERRIDE);
1048 if (ret)
1049 bpf_prog_put(prog);
David Ahernb2cd1252016-12-01 08:48:03 -08001050 cgroup_put(cgrp);
1051
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001052 return ret;
Daniel Mackf4324552016-11-23 16:52:27 +01001053}
1054
1055#define BPF_PROG_DETACH_LAST_FIELD attach_type
1056
1057static int bpf_prog_detach(const union bpf_attr *attr)
1058{
1059 struct cgroup *cgrp;
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001060 int ret;
Daniel Mackf4324552016-11-23 16:52:27 +01001061
1062 if (!capable(CAP_NET_ADMIN))
1063 return -EPERM;
1064
1065 if (CHECK_ATTR(BPF_PROG_DETACH))
1066 return -EINVAL;
1067
1068 switch (attr->attach_type) {
1069 case BPF_CGROUP_INET_INGRESS:
1070 case BPF_CGROUP_INET_EGRESS:
David Ahern610236582016-12-01 08:48:04 -08001071 case BPF_CGROUP_INET_SOCK_CREATE:
Daniel Mackf4324552016-11-23 16:52:27 +01001072 cgrp = cgroup_get_from_fd(attr->target_fd);
1073 if (IS_ERR(cgrp))
1074 return PTR_ERR(cgrp);
1075
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001076 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
Daniel Mackf4324552016-11-23 16:52:27 +01001077 cgroup_put(cgrp);
1078 break;
1079
1080 default:
1081 return -EINVAL;
1082 }
1083
Alexei Starovoitov7f677632017-02-10 20:28:24 -08001084 return ret;
Daniel Mackf4324552016-11-23 16:52:27 +01001085}
1086#endif /* CONFIG_CGROUP_BPF */
1087
Alexei Starovoitov1cf1cae2017-03-30 21:45:38 -07001088#define BPF_PROG_TEST_RUN_LAST_FIELD test.duration
1089
1090static int bpf_prog_test_run(const union bpf_attr *attr,
1091 union bpf_attr __user *uattr)
1092{
1093 struct bpf_prog *prog;
1094 int ret = -ENOTSUPP;
1095
1096 if (CHECK_ATTR(BPF_PROG_TEST_RUN))
1097 return -EINVAL;
1098
1099 prog = bpf_prog_get(attr->test.prog_fd);
1100 if (IS_ERR(prog))
1101 return PTR_ERR(prog);
1102
1103 if (prog->aux->ops->test_run)
1104 ret = prog->aux->ops->test_run(prog, attr, uattr);
1105
1106 bpf_prog_put(prog);
1107 return ret;
1108}
1109
Martin KaFai Lau34ad5582017-06-05 12:15:48 -07001110#define BPF_OBJ_GET_NEXT_ID_LAST_FIELD next_id
1111
1112static int bpf_obj_get_next_id(const union bpf_attr *attr,
1113 union bpf_attr __user *uattr,
1114 struct idr *idr,
1115 spinlock_t *lock)
1116{
1117 u32 next_id = attr->start_id;
1118 int err = 0;
1119
1120 if (CHECK_ATTR(BPF_OBJ_GET_NEXT_ID) || next_id >= INT_MAX)
1121 return -EINVAL;
1122
1123 if (!capable(CAP_SYS_ADMIN))
1124 return -EPERM;
1125
1126 next_id++;
1127 spin_lock_bh(lock);
1128 if (!idr_get_next(idr, &next_id))
1129 err = -ENOENT;
1130 spin_unlock_bh(lock);
1131
1132 if (!err)
1133 err = put_user(next_id, &uattr->next_id);
1134
1135 return err;
1136}
1137
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -07001138#define BPF_PROG_GET_FD_BY_ID_LAST_FIELD prog_id
1139
1140static int bpf_prog_get_fd_by_id(const union bpf_attr *attr)
1141{
1142 struct bpf_prog *prog;
1143 u32 id = attr->prog_id;
1144 int fd;
1145
1146 if (CHECK_ATTR(BPF_PROG_GET_FD_BY_ID))
1147 return -EINVAL;
1148
1149 if (!capable(CAP_SYS_ADMIN))
1150 return -EPERM;
1151
1152 spin_lock_bh(&prog_idr_lock);
1153 prog = idr_find(&prog_idr, id);
1154 if (prog)
1155 prog = bpf_prog_inc_not_zero(prog);
1156 else
1157 prog = ERR_PTR(-ENOENT);
1158 spin_unlock_bh(&prog_idr_lock);
1159
1160 if (IS_ERR(prog))
1161 return PTR_ERR(prog);
1162
1163 fd = bpf_prog_new_fd(prog);
1164 if (fd < 0)
1165 bpf_prog_put(prog);
1166
1167 return fd;
1168}
1169
Alexei Starovoitov99c55f72014-09-26 00:16:57 -07001170SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
1171{
1172 union bpf_attr attr = {};
1173 int err;
1174
Alexei Starovoitov1be7f752015-10-07 22:23:21 -07001175 if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
Alexei Starovoitov99c55f72014-09-26 00:16:57 -07001176 return -EPERM;
1177
1178 if (!access_ok(VERIFY_READ, uattr, 1))
1179 return -EFAULT;
1180
1181 if (size > PAGE_SIZE) /* silly large */
1182 return -E2BIG;
1183
1184 /* If we're handed a bigger struct than we know of,
1185 * ensure all the unknown bits are 0 - i.e. new
1186 * user-space does not rely on any kernel feature
1187 * extensions we dont know about yet.
1188 */
1189 if (size > sizeof(attr)) {
1190 unsigned char __user *addr;
1191 unsigned char __user *end;
1192 unsigned char val;
1193
1194 addr = (void __user *)uattr + sizeof(attr);
1195 end = (void __user *)uattr + size;
1196
1197 for (; addr < end; addr++) {
1198 err = get_user(val, addr);
1199 if (err)
1200 return err;
1201 if (val)
1202 return -E2BIG;
1203 }
1204 size = sizeof(attr);
1205 }
1206
1207 /* copy attributes from user space, may be less than sizeof(bpf_attr) */
1208 if (copy_from_user(&attr, uattr, size) != 0)
1209 return -EFAULT;
1210
1211 switch (cmd) {
1212 case BPF_MAP_CREATE:
1213 err = map_create(&attr);
1214 break;
Alexei Starovoitovdb20fd22014-09-26 00:16:59 -07001215 case BPF_MAP_LOOKUP_ELEM:
1216 err = map_lookup_elem(&attr);
1217 break;
1218 case BPF_MAP_UPDATE_ELEM:
1219 err = map_update_elem(&attr);
1220 break;
1221 case BPF_MAP_DELETE_ELEM:
1222 err = map_delete_elem(&attr);
1223 break;
1224 case BPF_MAP_GET_NEXT_KEY:
1225 err = map_get_next_key(&attr);
1226 break;
Alexei Starovoitov09756af2014-09-26 00:17:00 -07001227 case BPF_PROG_LOAD:
1228 err = bpf_prog_load(&attr);
1229 break;
Daniel Borkmannb2197752015-10-29 14:58:09 +01001230 case BPF_OBJ_PIN:
1231 err = bpf_obj_pin(&attr);
1232 break;
1233 case BPF_OBJ_GET:
1234 err = bpf_obj_get(&attr);
1235 break;
Daniel Mackf4324552016-11-23 16:52:27 +01001236#ifdef CONFIG_CGROUP_BPF
1237 case BPF_PROG_ATTACH:
1238 err = bpf_prog_attach(&attr);
1239 break;
1240 case BPF_PROG_DETACH:
1241 err = bpf_prog_detach(&attr);
1242 break;
1243#endif
Alexei Starovoitov1cf1cae2017-03-30 21:45:38 -07001244 case BPF_PROG_TEST_RUN:
1245 err = bpf_prog_test_run(&attr, uattr);
1246 break;
Martin KaFai Lau34ad5582017-06-05 12:15:48 -07001247 case BPF_PROG_GET_NEXT_ID:
1248 err = bpf_obj_get_next_id(&attr, uattr,
1249 &prog_idr, &prog_idr_lock);
1250 break;
1251 case BPF_MAP_GET_NEXT_ID:
1252 err = bpf_obj_get_next_id(&attr, uattr,
1253 &map_idr, &map_idr_lock);
1254 break;
Martin KaFai Laub16d9aa2017-06-05 12:15:49 -07001255 case BPF_PROG_GET_FD_BY_ID:
1256 err = bpf_prog_get_fd_by_id(&attr);
1257 break;
Alexei Starovoitov99c55f72014-09-26 00:16:57 -07001258 default:
1259 err = -EINVAL;
1260 break;
1261 }
1262
1263 return err;
1264}