lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Wed, 13 Apr 2022 16:41:17 +0300 From: Maxim Mikityanskiy <maximmi@...dia.com> To: <bpf@...r.kernel.org>, Alexei Starovoitov <ast@...nel.org>, "Daniel Borkmann" <daniel@...earbox.net>, Andrii Nakryiko <andrii@...nel.org>, <netdev@...r.kernel.org> CC: Tariq Toukan <tariqt@...dia.com>, Martin KaFai Lau <kafai@...com>, "Song Liu" <songliubraving@...com>, Yonghong Song <yhs@...com>, John Fastabend <john.fastabend@...il.com>, KP Singh <kpsingh@...nel.org>, "David S. Miller" <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>, Petar Penkov <ppenkov@...gle.com>, Lorenz Bauer <lmb@...udflare.com>, Eric Dumazet <edumazet@...gle.com>, Hideaki YOSHIFUJI <yoshfuji@...ux-ipv6.org>, "David Ahern" <dsahern@...nel.org>, Shuah Khan <shuah@...nel.org>, "Jesper Dangaard Brouer" <hawk@...nel.org>, Nathan Chancellor <nathan@...nel.org>, "Nick Desaulniers" <ndesaulniers@...gle.com>, Joe Stringer <joe@...ium.io>, "Florent Revest" <revest@...omium.org>, <linux-kselftest@...r.kernel.org>, Toke Høiland-Jørgensen <toke@...e.dk>, "Kumar Kartikeya Dwivedi" <memxor@...il.com>, Florian Westphal <fw@...len.de>, "Maxim Mikityanskiy" <maximmi@...dia.com> Subject: [PATCH bpf-next v5 3/6] bpf: Allow helpers to accept pointers with a fixed size Before this commit, the BPF verifier required ARG_PTR_TO_MEM arguments to be followed by ARG_CONST_SIZE holding the size of the memory region. The helpers had to check that size in runtime. There are cases where the size expected by a helper is a compile-time constant. Checking it in runtime is an unnecessary overhead and waste of BPF registers. This commit allows helpers to accept ARG_PTR_TO_MEM arguments without the corresponding ARG_CONST_SIZE, given that they define the memory region size in struct bpf_func_proto. Signed-off-by: Maxim Mikityanskiy <maximmi@...dia.com> Reviewed-by: Tariq Toukan <tariqt@...dia.com> --- include/linux/bpf.h | 10 ++++++++++ kernel/bpf/verifier.c | 26 +++++++++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 88449fbbe063..988749057610 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -465,6 +465,16 @@ struct bpf_func_proto { }; u32 *arg_btf_id[5]; }; + union { + struct { + size_t arg1_size; + size_t arg2_size; + size_t arg3_size; + size_t arg4_size; + size_t arg5_size; + }; + size_t arg_size[5]; + }; int *ret_btf_id; /* return value btf_id */ bool (*allowed)(const struct bpf_prog *prog); }; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 571ccd7f04eb..1b4c1e9ce8b2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5573,6 +5573,11 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, * next is_mem_size argument below. */ meta->raw_mode = (arg_type == ARG_PTR_TO_UNINIT_MEM); + if (fn->arg_size[arg]) { + err = check_helper_mem_access(env, regno, + fn->arg_size[arg], false, + meta); + } } else if (arg_type_is_mem_size(arg_type)) { bool zero_size_allowed = (arg_type == ARG_CONST_SIZE_OR_ZERO); @@ -5912,13 +5917,12 @@ static bool check_raw_mode_ok(const struct bpf_func_proto *fn) return count <= 1; } -static bool check_args_pair_invalid(enum bpf_arg_type arg_curr, - enum bpf_arg_type arg_next) +static bool check_args_pair_invalid(const struct bpf_func_proto *fn, int arg) { - return (arg_type_is_mem_ptr(arg_curr) && - !arg_type_is_mem_size(arg_next)) || - (!arg_type_is_mem_ptr(arg_curr) && - arg_type_is_mem_size(arg_next)); + if (arg_type_is_mem_ptr(fn->arg_type[arg])) + return arg_type_is_mem_size(fn->arg_type[arg + 1]) == + !!fn->arg_size[arg]; + return arg_type_is_mem_size(fn->arg_type[arg + 1]) || fn->arg_size[arg]; } static bool check_arg_pair_ok(const struct bpf_func_proto *fn) @@ -5929,11 +5933,11 @@ static bool check_arg_pair_ok(const struct bpf_func_proto *fn) * helper function specification. */ if (arg_type_is_mem_size(fn->arg1_type) || - arg_type_is_mem_ptr(fn->arg5_type) || - check_args_pair_invalid(fn->arg1_type, fn->arg2_type) || - check_args_pair_invalid(fn->arg2_type, fn->arg3_type) || - check_args_pair_invalid(fn->arg3_type, fn->arg4_type) || - check_args_pair_invalid(fn->arg4_type, fn->arg5_type)) + (arg_type_is_mem_ptr(fn->arg5_type) && !fn->arg5_size) || + check_args_pair_invalid(fn, 1) || + check_args_pair_invalid(fn, 2) || + check_args_pair_invalid(fn, 3) || + check_args_pair_invalid(fn, 4)) return false; return true; -- 2.30.2
Powered by blists - more mailing lists