Re: [PATCH v2 0/3] bpf: switch to new usercopy helpers

From: Christian Brauner
Date: Tue Oct 15 2019 - 23:31:27 EST


On Tue, Oct 15, 2019 at 07:14:42PM -0700, Alexei Starovoitov wrote:
> On Tue, Oct 15, 2019 at 5:41 PM Christian Brauner
> <christian.brauner@xxxxxxxxxx> wrote:
> >
> > Hey everyone,
> >
> > In v5.4-rc2 we added two new helpers check_zeroed_user() and
> > copy_struct_from_user() including selftests (cf. [1]). It is a generic
> > interface designed to copy a struct from userspace. The helpers will be
> > especially useful for structs versioned by size of which we have quite a
> > few.
>
> Was it tested?
> Either your conversion is incorrect or that generic helper is broken.
> ./test_progs -n 2
> and
> ./test_btf
> are catching the bug:
> BTF prog info raw test[8] (line_info (No subprog. zero tailing
> line_info): do_test_info_raw:6205:FAIL prog_fd:-1
> expected_prog_load_failure:0 errno:7
> nonzero tailing record in line_infoprocessed 0 insns (limit 1000000)
> max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

Ugh, I misrememberd what the helper I helped design returns. The fix is:

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 5db9887a8f4c..0920593eacd0 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -78,11 +78,8 @@ int bpf_check_uarg_tail_zero(void __user *uaddr,
return 0;

err = check_zeroed_user(uaddr + expected_size, rest);
- if (err < 0)
- return err;
-
- if (err)
- return -E2BIG;
+ if (err <= 0)
+ return err ?: -E2BIG;

return 0;
}

aka check_zeroed_user() returns 0 if non-zero bytes are present, 1 if no
non-zero bytes were present, and -errno on error.

I'll send a fixed version. The tests pass for me with this.

Christian