mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-10 23:29:46 +00:00
bpf: fix loading of BPF_MAXINSNS sized programs
General assumption is that single program can hold up to BPF_MAXINSNS, that is, 4096 number of instructions. It is the case with cBPF and that limit was carried over to eBPF. When recently testing digest, I noticed that it's actually not possible to feed 4096 instructions via bpf(2). The check for > BPF_MAXINSNS was added back then to bpf_check() in cbd357008604 ("bpf: verifier (add ability to receive verification log)"). However, 09756af46893 ("bpf: expand BPF syscall with program load/unload") added yet another check that comes before that into bpf_prog_load(), but this time bails out already in case of >= BPF_MAXINSNS. Fix it up and perform the check early in bpf_prog_load(), so we can drop the second one in bpf_check(). It makes sense, because also a 0 insn program is useless and we don't want to waste any resources doing work up to bpf_check() point. The existing bpf(2) man page documents E2BIG as the official error for such cases, so just stick with it as well. Fixes: 09756af46893 ("bpf: expand BPF syscall with program load/unload") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
90364feaf7
commit
ef0915cacd
@ -786,8 +786,8 @@ static int bpf_prog_load(union bpf_attr *attr)
|
|||||||
/* eBPF programs must be GPL compatible to use GPL-ed functions */
|
/* eBPF programs must be GPL compatible to use GPL-ed functions */
|
||||||
is_gpl = license_is_gpl_compatible(license);
|
is_gpl = license_is_gpl_compatible(license);
|
||||||
|
|
||||||
if (attr->insn_cnt >= BPF_MAXINSNS)
|
if (attr->insn_cnt == 0 || attr->insn_cnt > BPF_MAXINSNS)
|
||||||
return -EINVAL;
|
return -E2BIG;
|
||||||
|
|
||||||
if (type == BPF_PROG_TYPE_KPROBE &&
|
if (type == BPF_PROG_TYPE_KPROBE &&
|
||||||
attr->kern_version != LINUX_VERSION_CODE)
|
attr->kern_version != LINUX_VERSION_CODE)
|
||||||
|
@ -3133,9 +3133,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
|
|||||||
struct bpf_verifier_env *env;
|
struct bpf_verifier_env *env;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if ((*prog)->len <= 0 || (*prog)->len > BPF_MAXINSNS)
|
|
||||||
return -E2BIG;
|
|
||||||
|
|
||||||
/* 'struct bpf_verifier_env' can be global, but since it's not small,
|
/* 'struct bpf_verifier_env' can be global, but since it's not small,
|
||||||
* allocate/free it every time bpf_check() is called
|
* allocate/free it every time bpf_check() is called
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user