verifier.c (79a7f8bdb159d9914b58740f3d31d602a6e4aca8) verifier.c (af2ac3e13e45752af03c8a933f9b6e18841b128b)
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
3 * Copyright (c) 2016 Facebook
4 * Copyright (c) 2018 Covalent IO, Inc. http://covalent.io
5 */
6#include <uapi/linux/btf.h>
7#include <linux/kernel.h>
8#include <linux/types.h>

--- 9422 unchanged lines hidden (view full) ---

9431}
9432
9433/* The minimum supported BTF func info size */
9434#define MIN_BPF_FUNCINFO_SIZE 8
9435#define MAX_FUNCINFO_REC_SIZE 252
9436
9437static int check_btf_func(struct bpf_verifier_env *env,
9438 const union bpf_attr *attr,
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
3 * Copyright (c) 2016 Facebook
4 * Copyright (c) 2018 Covalent IO, Inc. http://covalent.io
5 */
6#include <uapi/linux/btf.h>
7#include <linux/kernel.h>
8#include <linux/types.h>

--- 9422 unchanged lines hidden (view full) ---

9431}
9432
9433/* The minimum supported BTF func info size */
9434#define MIN_BPF_FUNCINFO_SIZE 8
9435#define MAX_FUNCINFO_REC_SIZE 252
9436
9437static int check_btf_func(struct bpf_verifier_env *env,
9438 const union bpf_attr *attr,
9439 union bpf_attr __user *uattr)
9439 bpfptr_t uattr)
9440{
9441 const struct btf_type *type, *func_proto, *ret_type;
9442 u32 i, nfuncs, urec_size, min_size;
9443 u32 krec_size = sizeof(struct bpf_func_info);
9444 struct bpf_func_info *krecord;
9445 struct bpf_func_info_aux *info_aux = NULL;
9446 struct bpf_prog *prog;
9447 const struct btf *btf;
9440{
9441 const struct btf_type *type, *func_proto, *ret_type;
9442 u32 i, nfuncs, urec_size, min_size;
9443 u32 krec_size = sizeof(struct bpf_func_info);
9444 struct bpf_func_info *krecord;
9445 struct bpf_func_info_aux *info_aux = NULL;
9446 struct bpf_prog *prog;
9447 const struct btf *btf;
9448 void __user *urecord;
9448 bpfptr_t urecord;
9449 u32 prev_offset = 0;
9450 bool scalar_return;
9451 int ret = -ENOMEM;
9452
9453 nfuncs = attr->func_info_cnt;
9454 if (!nfuncs) {
9455 if (check_abnormal_return(env))
9456 return -EINVAL;

--- 11 unchanged lines hidden (view full) ---

9468 urec_size % sizeof(u32)) {
9469 verbose(env, "invalid func info rec size %u\n", urec_size);
9470 return -EINVAL;
9471 }
9472
9473 prog = env->prog;
9474 btf = prog->aux->btf;
9475
9449 u32 prev_offset = 0;
9450 bool scalar_return;
9451 int ret = -ENOMEM;
9452
9453 nfuncs = attr->func_info_cnt;
9454 if (!nfuncs) {
9455 if (check_abnormal_return(env))
9456 return -EINVAL;

--- 11 unchanged lines hidden (view full) ---

9468 urec_size % sizeof(u32)) {
9469 verbose(env, "invalid func info rec size %u\n", urec_size);
9470 return -EINVAL;
9471 }
9472
9473 prog = env->prog;
9474 btf = prog->aux->btf;
9475
9476 urecord = u64_to_user_ptr(attr->func_info);
9476 urecord = make_bpfptr(attr->func_info, uattr.is_kernel);
9477 min_size = min_t(u32, krec_size, urec_size);
9478
9479 krecord = kvcalloc(nfuncs, krec_size, GFP_KERNEL | __GFP_NOWARN);
9480 if (!krecord)
9481 return -ENOMEM;
9482 info_aux = kcalloc(nfuncs, sizeof(*info_aux), GFP_KERNEL | __GFP_NOWARN);
9483 if (!info_aux)
9484 goto err_free;
9485
9486 for (i = 0; i < nfuncs; i++) {
9487 ret = bpf_check_uarg_tail_zero(urecord, krec_size, urec_size);
9488 if (ret) {
9489 if (ret == -E2BIG) {
9490 verbose(env, "nonzero tailing record in func info");
9491 /* set the size kernel expects so loader can zero
9492 * out the rest of the record.
9493 */
9477 min_size = min_t(u32, krec_size, urec_size);
9478
9479 krecord = kvcalloc(nfuncs, krec_size, GFP_KERNEL | __GFP_NOWARN);
9480 if (!krecord)
9481 return -ENOMEM;
9482 info_aux = kcalloc(nfuncs, sizeof(*info_aux), GFP_KERNEL | __GFP_NOWARN);
9483 if (!info_aux)
9484 goto err_free;
9485
9486 for (i = 0; i < nfuncs; i++) {
9487 ret = bpf_check_uarg_tail_zero(urecord, krec_size, urec_size);
9488 if (ret) {
9489 if (ret == -E2BIG) {
9490 verbose(env, "nonzero tailing record in func info");
9491 /* set the size kernel expects so loader can zero
9492 * out the rest of the record.
9493 */
9494 if (put_user(min_size, &uattr->func_info_rec_size))
9494 if (copy_to_bpfptr_offset(uattr,
9495 offsetof(union bpf_attr, func_info_rec_size),
9496 &min_size, sizeof(min_size)))
9495 ret = -EFAULT;
9496 }
9497 goto err_free;
9498 }
9499
9497 ret = -EFAULT;
9498 }
9499 goto err_free;
9500 }
9501
9500 if (copy_from_user(&krecord[i], urecord, min_size)) {
9502 if (copy_from_bpfptr(&krecord[i], urecord, min_size)) {
9501 ret = -EFAULT;
9502 goto err_free;
9503 }
9504
9505 /* check insn_off */
9506 ret = -EINVAL;
9507 if (i == 0) {
9508 if (krecord[i].insn_off) {

--- 35 unchanged lines hidden (view full) ---

9544 goto err_free;
9545 }
9546 if (i && !scalar_return && env->subprog_info[i].has_tail_call) {
9547 verbose(env, "tail_call is only allowed in functions that return 'int'.\n");
9548 goto err_free;
9549 }
9550
9551 prev_offset = krecord[i].insn_off;
9503 ret = -EFAULT;
9504 goto err_free;
9505 }
9506
9507 /* check insn_off */
9508 ret = -EINVAL;
9509 if (i == 0) {
9510 if (krecord[i].insn_off) {

--- 35 unchanged lines hidden (view full) ---

9546 goto err_free;
9547 }
9548 if (i && !scalar_return && env->subprog_info[i].has_tail_call) {
9549 verbose(env, "tail_call is only allowed in functions that return 'int'.\n");
9550 goto err_free;
9551 }
9552
9553 prev_offset = krecord[i].insn_off;
9552 urecord += urec_size;
9554 bpfptr_add(&urecord, urec_size);
9553 }
9554
9555 prog->aux->func_info = krecord;
9556 prog->aux->func_info_cnt = nfuncs;
9557 prog->aux->func_info_aux = info_aux;
9558 return 0;
9559
9560err_free:

--- 15 unchanged lines hidden (view full) ---

9576}
9577
9578#define MIN_BPF_LINEINFO_SIZE (offsetof(struct bpf_line_info, line_col) + \
9579 sizeof(((struct bpf_line_info *)(0))->line_col))
9580#define MAX_LINEINFO_REC_SIZE MAX_FUNCINFO_REC_SIZE
9581
9582static int check_btf_line(struct bpf_verifier_env *env,
9583 const union bpf_attr *attr,
9555 }
9556
9557 prog->aux->func_info = krecord;
9558 prog->aux->func_info_cnt = nfuncs;
9559 prog->aux->func_info_aux = info_aux;
9560 return 0;
9561
9562err_free:

--- 15 unchanged lines hidden (view full) ---

9578}
9579
9580#define MIN_BPF_LINEINFO_SIZE (offsetof(struct bpf_line_info, line_col) + \
9581 sizeof(((struct bpf_line_info *)(0))->line_col))
9582#define MAX_LINEINFO_REC_SIZE MAX_FUNCINFO_REC_SIZE
9583
9584static int check_btf_line(struct bpf_verifier_env *env,
9585 const union bpf_attr *attr,
9584 union bpf_attr __user *uattr)
9586 bpfptr_t uattr)
9585{
9586 u32 i, s, nr_linfo, ncopy, expected_size, rec_size, prev_offset = 0;
9587 struct bpf_subprog_info *sub;
9588 struct bpf_line_info *linfo;
9589 struct bpf_prog *prog;
9590 const struct btf *btf;
9587{
9588 u32 i, s, nr_linfo, ncopy, expected_size, rec_size, prev_offset = 0;
9589 struct bpf_subprog_info *sub;
9590 struct bpf_line_info *linfo;
9591 struct bpf_prog *prog;
9592 const struct btf *btf;
9591 void __user *ulinfo;
9593 bpfptr_t ulinfo;
9592 int err;
9593
9594 nr_linfo = attr->line_info_cnt;
9595 if (!nr_linfo)
9596 return 0;
9597
9598 rec_size = attr->line_info_rec_size;
9599 if (rec_size < MIN_BPF_LINEINFO_SIZE ||

--- 9 unchanged lines hidden (view full) ---

9609 if (!linfo)
9610 return -ENOMEM;
9611
9612 prog = env->prog;
9613 btf = prog->aux->btf;
9614
9615 s = 0;
9616 sub = env->subprog_info;
9594 int err;
9595
9596 nr_linfo = attr->line_info_cnt;
9597 if (!nr_linfo)
9598 return 0;
9599
9600 rec_size = attr->line_info_rec_size;
9601 if (rec_size < MIN_BPF_LINEINFO_SIZE ||

--- 9 unchanged lines hidden (view full) ---

9611 if (!linfo)
9612 return -ENOMEM;
9613
9614 prog = env->prog;
9615 btf = prog->aux->btf;
9616
9617 s = 0;
9618 sub = env->subprog_info;
9617 ulinfo = u64_to_user_ptr(attr->line_info);
9619 ulinfo = make_bpfptr(attr->line_info, uattr.is_kernel);
9618 expected_size = sizeof(struct bpf_line_info);
9619 ncopy = min_t(u32, expected_size, rec_size);
9620 for (i = 0; i < nr_linfo; i++) {
9621 err = bpf_check_uarg_tail_zero(ulinfo, expected_size, rec_size);
9622 if (err) {
9623 if (err == -E2BIG) {
9624 verbose(env, "nonzero tailing record in line_info");
9620 expected_size = sizeof(struct bpf_line_info);
9621 ncopy = min_t(u32, expected_size, rec_size);
9622 for (i = 0; i < nr_linfo; i++) {
9623 err = bpf_check_uarg_tail_zero(ulinfo, expected_size, rec_size);
9624 if (err) {
9625 if (err == -E2BIG) {
9626 verbose(env, "nonzero tailing record in line_info");
9625 if (put_user(expected_size,
9626 &uattr->line_info_rec_size))
9627 if (copy_to_bpfptr_offset(uattr,
9628 offsetof(union bpf_attr, line_info_rec_size),
9629 &expected_size, sizeof(expected_size)))
9627 err = -EFAULT;
9628 }
9629 goto err_free;
9630 }
9631
9630 err = -EFAULT;
9631 }
9632 goto err_free;
9633 }
9634
9632 if (copy_from_user(&linfo[i], ulinfo, ncopy)) {
9635 if (copy_from_bpfptr(&linfo[i], ulinfo, ncopy)) {
9633 err = -EFAULT;
9634 goto err_free;
9635 }
9636
9637 /*
9638 * Check insn_off to ensure
9639 * 1) strictly increasing AND
9640 * 2) bounded by prog->len

--- 35 unchanged lines hidden (view full) ---

9676 } else if (sub[s].start < linfo[i].insn_off) {
9677 verbose(env, "missing bpf_line_info for func#%u\n", s);
9678 err = -EINVAL;
9679 goto err_free;
9680 }
9681 }
9682
9683 prev_offset = linfo[i].insn_off;
9636 err = -EFAULT;
9637 goto err_free;
9638 }
9639
9640 /*
9641 * Check insn_off to ensure
9642 * 1) strictly increasing AND
9643 * 2) bounded by prog->len

--- 35 unchanged lines hidden (view full) ---

9679 } else if (sub[s].start < linfo[i].insn_off) {
9680 verbose(env, "missing bpf_line_info for func#%u\n", s);
9681 err = -EINVAL;
9682 goto err_free;
9683 }
9684 }
9685
9686 prev_offset = linfo[i].insn_off;
9684 ulinfo += rec_size;
9687 bpfptr_add(&ulinfo, rec_size);
9685 }
9686
9687 if (s != env->subprog_cnt) {
9688 verbose(env, "missing bpf_line_info for %u funcs starting from func#%u\n",
9689 env->subprog_cnt - s, s);
9690 err = -EINVAL;
9691 goto err_free;
9692 }

--- 5 unchanged lines hidden (view full) ---

9698
9699err_free:
9700 kvfree(linfo);
9701 return err;
9702}
9703
9704static int check_btf_info(struct bpf_verifier_env *env,
9705 const union bpf_attr *attr,
9688 }
9689
9690 if (s != env->subprog_cnt) {
9691 verbose(env, "missing bpf_line_info for %u funcs starting from func#%u\n",
9692 env->subprog_cnt - s, s);
9693 err = -EINVAL;
9694 goto err_free;
9695 }

--- 5 unchanged lines hidden (view full) ---

9701
9702err_free:
9703 kvfree(linfo);
9704 return err;
9705}
9706
9707static int check_btf_info(struct bpf_verifier_env *env,
9708 const union bpf_attr *attr,
9706 union bpf_attr __user *uattr)
9709 bpfptr_t uattr)
9707{
9708 struct btf *btf;
9709 int err;
9710
9711 if (!attr->func_info_cnt && !attr->line_info_cnt) {
9712 if (check_abnormal_return(env))
9713 return -EINVAL;
9714 return 0;

--- 3555 unchanged lines hidden (view full) ---

13270 mutex_lock(&bpf_verifier_lock);
13271 if (!btf_vmlinux)
13272 btf_vmlinux = btf_parse_vmlinux();
13273 mutex_unlock(&bpf_verifier_lock);
13274 }
13275 return btf_vmlinux;
13276}
13277
9710{
9711 struct btf *btf;
9712 int err;
9713
9714 if (!attr->func_info_cnt && !attr->line_info_cnt) {
9715 if (check_abnormal_return(env))
9716 return -EINVAL;
9717 return 0;

--- 3555 unchanged lines hidden (view full) ---

13273 mutex_lock(&bpf_verifier_lock);
13274 if (!btf_vmlinux)
13275 btf_vmlinux = btf_parse_vmlinux();
13276 mutex_unlock(&bpf_verifier_lock);
13277 }
13278 return btf_vmlinux;
13279}
13280
13278int bpf_check(struct bpf_prog **prog, union bpf_attr *attr,
13279 union bpf_attr __user *uattr)
13281int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr)
13280{
13281 u64 start_time = ktime_get_ns();
13282 struct bpf_verifier_env *env;
13283 struct bpf_verifier_log *log;
13284 int i, len, ret = -EINVAL;
13285 bool is_priv;
13286
13287 /* no program is valid */

--- 223 unchanged lines hidden ---
13282{
13283 u64 start_time = ktime_get_ns();
13284 struct bpf_verifier_env *env;
13285 struct bpf_verifier_log *log;
13286 int i, len, ret = -EINVAL;
13287 bool is_priv;
13288
13289 /* no program is valid */

--- 223 unchanged lines hidden ---