projects
/
platform
/
kernel
/
linux-starfive.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
80123f0
)
bpf: test_run: Fix overflow in xdp frags parsing
author
Stanislav Fomichev
<sdf@google.com>
Fri, 4 Feb 2022 23:58:48 +0000
(15:58 -0800)
committer
Alexei Starovoitov
<ast@kernel.org>
Tue, 8 Feb 2022 02:26:13 +0000
(18:26 -0800)
When kattr->test.data_size_in > INT_MAX, signed min_t will assign
negative value to data_len. This negative value then gets passed
over to copy_from_user where it is converted to (big) unsigned.
Use unsigned min_t to avoid this overflow.
usercopy: Kernel memory overwrite attempt detected to wrapped address
(offset 0, size
18446612140539162846
)!
------------[ cut here ]------------
kernel BUG at mm/usercopy.c:102!
invalid opcode: 0000 [#1] SMP KASAN
Modules linked in:
CPU: 0 PID: 3781 Comm: syz-executor226 Not tainted 4.15.0-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:usercopy_abort+0xbd/0xbf mm/usercopy.c:102
RSP: 0018:
ffff8801e9703a38
EFLAGS:
00010286
RAX:
000000000000006c
RBX:
ffffffff84fc7040
RCX:
0000000000000000
RDX:
0000000000000000
RSI:
ffffffff816560a2
RDI:
ffffed003d2e0739
RBP:
ffff8801e9703a90
R08:
000000000000006c
R09:
0000000000000001
R10:
0000000000000000
R11:
0000000000000000
R12:
ffffffff84fc73a0
R13:
ffffffff84fc7180
R14:
ffffffff84fc7040
R15:
ffffffff84fc7040
FS:
00007f54e0bec300
(0000) GS:
ffff8801f6600000
(0000)
knlGS:
0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
CR2:
0000000020000280
CR3:
00000001e90ea000
CR4:
00000000003426f0
DR0:
0000000000000000
DR1:
0000000000000000
DR2:
0000000000000000
DR3:
0000000000000000
DR6:
00000000fffe0ff0
DR7:
0000000000000400
Call Trace:
check_bogus_address mm/usercopy.c:155 [inline]
__check_object_size mm/usercopy.c:263 [inline]
__check_object_size.cold+0x8c/0xad mm/usercopy.c:253
check_object_size include/linux/thread_info.h:112 [inline]
check_copy_size include/linux/thread_info.h:143 [inline]
copy_from_user include/linux/uaccess.h:142 [inline]
bpf_prog_test_run_xdp+0xe57/0x1240 net/bpf/test_run.c:989
bpf_prog_test_run kernel/bpf/syscall.c:3377 [inline]
__sys_bpf+0xdf2/0x4a50 kernel/bpf/syscall.c:4679
SYSC_bpf kernel/bpf/syscall.c:4765 [inline]
SyS_bpf+0x26/0x50 kernel/bpf/syscall.c:4763
do_syscall_64+0x21a/0x3e0 arch/x86/entry/common.c:305
entry_SYSCALL_64_after_hwframe+0x46/0xbb
Fixes:
1c1949982524
("bpf: introduce frags support to bpf_prog_test_run_xdp()")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link:
https://lore.kernel.org/bpf/20220204235849.14658-1-sdf@google.com
net/bpf/test_run.c
patch
|
blob
|
history
diff --git
a/net/bpf/test_run.c
b/net/bpf/test_run.c
index
0220b08
..
5819a7a
100644
(file)
--- a/
net/bpf/test_run.c
+++ b/
net/bpf/test_run.c
@@
-960,7
+960,7
@@
int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
while (size < kattr->test.data_size_in) {
struct page *page;
skb_frag_t *frag;
-
int
data_len;
+
u32
data_len;
if (sinfo->nr_frags == MAX_SKB_FRAGS) {
ret = -ENOMEM;
@@
-976,7
+976,7
@@
int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
frag = &sinfo->frags[sinfo->nr_frags++];
__skb_frag_set_page(frag, page);
- data_len = min_t(
int
, kattr->test.data_size_in - size,
+ data_len = min_t(
u32
, kattr->test.data_size_in - size,
PAGE_SIZE);
skb_frag_size_set(frag, data_len);