On Thu, May 26, 2022 at 08:31:10AM -0700, Yonghong Song wrote: > > > On 5/26/22 3:24 AM, Dan Carpenter wrote: > > The kvmalloc_array() function is safer because it has a check for > > integer overflows. These sizes come from the user and I was not > > able to see any bounds checking so an integer overflow seems like a > > realistic concern. > > > > Fixes: 0dcac2725406 ("bpf: Add multi kprobe link") > > Signed-off-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx> > > --- > > kernel/trace/bpf_trace.c | 8 ++++---- > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > > index 10b157a6d73e..7a13e6ac6327 100644 > > --- a/kernel/trace/bpf_trace.c > > +++ b/kernel/trace/bpf_trace.c > > @@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32 > > int err = -ENOMEM; > > unsigned int i; > > - syms = kvmalloc(cnt * sizeof(*syms), GFP_KERNEL); > > + syms = kvmalloc_array(cnt, sizeof(*syms), GFP_KERNEL); > > if (!syms) > > goto error; > > - buf = kvmalloc(cnt * KSYM_NAME_LEN, GFP_KERNEL); > > + buf = kvmalloc_array(cnt, KSYM_NAME_LEN, GFP_KERNEL); > > if (!buf) > > goto error; > > @@ -2464,7 +2464,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr > > For this part of change, there is a similar pending patch here: > https://lore.kernel.org/bpf/399e634781822329e856103cddba975f58f0498c.1652982525.git.esyr@xxxxxxxxxx/ > which waits for further review. That patch tries to detect the overflow > explicitly to avoid possible kernel dmesg warnings. (See function > kvmalloc_node()). That patch doesn't apply any more. Static checkers will insist that kvmalloc_array() is cleaner and safer than kvmalloc(n * size, and they don't care if the integer overflow is real or not. -EOVERFLOW is the wrong error code. Just return -ENOMEM. Checking for size > INT_MAX is ugly. Use a correct limit based on what the maximum reasonable size is. Or if we only want to prevent the stack dump then just pass __GFP_NOWARN. It annoyed me that size was type unsigned int. Sizes should be unsigned long. Every alloc() function takes an unsigned long so using a u32 temporary value for the size is what made this code so dangerous. If it had been: addrs = kvmalloc(cnt * sizeof(*addrs), GFP_KERNEL); instead of: size = cnt * sizeof(*addrs); addrs = kvmalloc(size, GFP_KERNEL); Then the integer overflow bug would only have affected 32 bit systems and those are pretty rare. Choosing the wrong type took a minor bug and made it affect everyone. regards, dan carpenter