bpf: Use safer kvmalloc_array() where possible
Subsystems (5)
PATCH 1/1 bpf: Use safer kvmalloc_array() where possible
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.
--- kernel/trace/bpf_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
kernel/trace/bpf_trace.c +4 -4
@@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32int 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 *prreturn -EINVAL ; size = cnt *sizeof (*addrs); - addrs =kvmalloc (size,GFP_KERNEL ); + addrs =kvmalloc_array (cnt,sizeof (*addrs),GFP_KERNEL );if (!addrs)return -ENOMEM ;
@@ -2489,7 +2489,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr ucookies =u64_to_user_ptr (attr->link_create.kprobe_multi.cookies);if (ucookies) { - cookies =kvmalloc (size,GFP_KERNEL ); + cookies =kvmalloc_array (cnt,sizeof (*addrs),GFP_KERNEL );if (!cookies) { err = -ENOMEM ; goto error;
Signature · 1 line
2.35.1
kernel/trace/bpf_trace.c int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
Quoted 30 lines · Dan Carpenter
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 <[email protected]>--- kernel/trace/bpf_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)kernel/trace/bpf_trace.c +2
-2@@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32int 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@redhat.com/
which waits for further review. That patch tries to detect the overflow explicitly to avoid possible kernel dmesg warnings. (See function kvmalloc_node()).
Quoted 17 lines
kernel/trace/bpf_trace.c +2
-2return -EINVAL ; size = cnt *sizeof (*addrs); - addrs =kvmalloc (size,GFP_KERNEL ); + addrs =kvmalloc_array (cnt,sizeof (*addrs),GFP_KERNEL );if (!addrs)return -ENOMEM ;@@ -2489,7 +2489,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr ucookies =u64_to_user_ptr (attr->link_create.kprobe_multi.cookies);if (ucookies) { - cookies =kvmalloc (size,GFP_KERNEL ); + cookies =kvmalloc_array (cnt,sizeof (*addrs),GFP_KERNEL );if (!cookies) { err = -ENOMEM ; goto error;
Quoted 28 lines · Yonghong Song
Quoted 25 lines · Dan Carpenter
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 <[email protected]>--- kernel/trace/bpf_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)kernel/trace/bpf_trace.c +2
-2@@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32int 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)
Quoted 8 lines
kernel/trace/bpf_trace.c int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
Quoted 2 lines
kernel/trace/bpf_trace.c +0
-0goto error;@@ -2464,7 +2464,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prFor this part of change, there is a similar pending patch here:
https://lore.kernel.org/bpf/399e634781822329e856103cddba975f58f0498c.1652982525.git.esyr@redhat.com/
which waits for further review. That patch tries to detect the overflow explicitly to avoid possible kernel dmesg warnings. (See functionkvmalloc_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
Quoted 7 lines · Dan Carpenter
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 <[email protected]>
Eugene was addressing these:
https://lore.kernel.org/bpf/399e634781822329e856103cddba975f58f0498c.1652982525.git.esyr@redhat.com/
I think using kvmalloc_array was one of the review comments
jirka
Quoted 43 lines
--- kernel/trace/bpf_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)kernel/trace/bpf_trace.c +4
-4@@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32int 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 *prreturn -EINVAL ; size = cnt *sizeof (*addrs); - addrs =kvmalloc (size,GFP_KERNEL ); + addrs =kvmalloc_array (cnt,sizeof (*addrs),GFP_KERNEL );if (!addrs)return -ENOMEM ;@@ -2489,7 +2489,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr ucookies =u64_to_user_ptr (attr->link_create.kprobe_multi.cookies);if (ucookies) { - cookies =kvmalloc (size,GFP_KERNEL ); + cookies =kvmalloc_array (cnt,sizeof (*addrs),GFP_KERNEL );if (!cookies) { err = -ENOMEM ; goto error;Signature · 1 line
2.35.1
This patch was applied to bpf/bpf-next.git (master) by Andrii Nakryiko <[email protected]>:
Hello:
This patch was applied to bpf/bpf-next.git (master) by Andrii Nakryiko <[email protected]>:
Quoted 9 lines · On Thu, 26 May 2022 13:24:05 +0300 you 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 <[email protected]>[...]
Here is the summary with links:
- bpf: Use safer kvmalloc_array() where possible
https://git.kernel.org/bpf/bpf-next/c/dafd0f870eae
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html