diff options
Diffstat (limited to 'kernel/bpf/inode.c')
-rw-r--r-- | kernel/bpf/inode.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index 01aaef1a77c5..5bb5e49ef4c3 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c | |||
@@ -368,7 +368,45 @@ out: | |||
368 | putname(pname); | 368 | putname(pname); |
369 | return ret; | 369 | return ret; |
370 | } | 370 | } |
371 | EXPORT_SYMBOL_GPL(bpf_obj_get_user); | 371 | |
372 | static struct bpf_prog *__get_prog_inode(struct inode *inode, enum bpf_prog_type type) | ||
373 | { | ||
374 | struct bpf_prog *prog; | ||
375 | int ret = inode_permission(inode, MAY_READ | MAY_WRITE); | ||
376 | if (ret) | ||
377 | return ERR_PTR(ret); | ||
378 | |||
379 | if (inode->i_op == &bpf_map_iops) | ||
380 | return ERR_PTR(-EINVAL); | ||
381 | if (inode->i_op != &bpf_prog_iops) | ||
382 | return ERR_PTR(-EACCES); | ||
383 | |||
384 | prog = inode->i_private; | ||
385 | |||
386 | ret = security_bpf_prog(prog); | ||
387 | if (ret < 0) | ||
388 | return ERR_PTR(ret); | ||
389 | |||
390 | if (!bpf_prog_get_ok(prog, &type, false)) | ||
391 | return ERR_PTR(-EINVAL); | ||
392 | |||
393 | return bpf_prog_inc(prog); | ||
394 | } | ||
395 | |||
396 | struct bpf_prog *bpf_prog_get_type_path(const char *name, enum bpf_prog_type type) | ||
397 | { | ||
398 | struct bpf_prog *prog; | ||
399 | struct path path; | ||
400 | int ret = kern_path(name, LOOKUP_FOLLOW, &path); | ||
401 | if (ret) | ||
402 | return ERR_PTR(ret); | ||
403 | prog = __get_prog_inode(d_backing_inode(path.dentry), type); | ||
404 | if (!IS_ERR(prog)) | ||
405 | touch_atime(&path); | ||
406 | path_put(&path); | ||
407 | return prog; | ||
408 | } | ||
409 | EXPORT_SYMBOL(bpf_prog_get_type_path); | ||
372 | 410 | ||
373 | static void bpf_evict_inode(struct inode *inode) | 411 | static void bpf_evict_inode(struct inode *inode) |
374 | { | 412 | { |