| From: Eric Dumazet <edumazet@google.com> |
| Date: Sat, 7 Apr 2018 13:42:40 -0700 |
| Subject: net: fix uninit-value in __hw_addr_add_ex() |
| |
| commit 77d36398d99f2565c0a8d43a86fd520a82e64bb8 upstream. |
| |
| syzbot complained : |
| |
| BUG: KMSAN: uninit-value in memcmp+0x119/0x180 lib/string.c:861 |
| CPU: 0 PID: 3 Comm: kworker/0:0 Not tainted 4.16.0+ #82 |
| Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 |
| Workqueue: ipv6_addrconf addrconf_dad_work |
| Call Trace: |
| __dump_stack lib/dump_stack.c:17 [inline] |
| dump_stack+0x185/0x1d0 lib/dump_stack.c:53 |
| kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 |
| __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676 |
| memcmp+0x119/0x180 lib/string.c:861 |
| __hw_addr_add_ex net/core/dev_addr_lists.c:60 [inline] |
| __dev_mc_add+0x1c2/0x8e0 net/core/dev_addr_lists.c:670 |
| dev_mc_add+0x6d/0x80 net/core/dev_addr_lists.c:687 |
| igmp6_group_added+0x2db/0xa00 net/ipv6/mcast.c:662 |
| ipv6_dev_mc_inc+0xe9e/0x1130 net/ipv6/mcast.c:914 |
| addrconf_join_solict net/ipv6/addrconf.c:2078 [inline] |
| addrconf_dad_begin net/ipv6/addrconf.c:3828 [inline] |
| addrconf_dad_work+0x427/0x2150 net/ipv6/addrconf.c:3954 |
| process_one_work+0x12c6/0x1f60 kernel/workqueue.c:2113 |
| worker_thread+0x113c/0x24f0 kernel/workqueue.c:2247 |
| kthread+0x539/0x720 kernel/kthread.c:239 |
| |
| Fixes: f001fde5eadd ("net: introduce a list of device addresses dev_addr_list (v6)") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Reported-by: syzbot <syzkaller@googlegroups.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/core/dev_addr_lists.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/net/core/dev_addr_lists.c |
| +++ b/net/core/dev_addr_lists.c |
| @@ -57,8 +57,8 @@ static int __hw_addr_add_ex(struct netde |
| return -EINVAL; |
| |
| list_for_each_entry(ha, &list->list, list) { |
| - if (!memcmp(ha->addr, addr, addr_len) && |
| - ha->type == addr_type) { |
| + if (ha->type == addr_type && |
| + !memcmp(ha->addr, addr, addr_len)) { |
| if (global) { |
| /* check if addr is already used as global */ |
| if (ha->global_use) |