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 --- |