]>
Commit | Line | Data |
---|---|---|
8cbcfc8d GKH |
1 | From foo@baz Fri Mar 15 21:00:09 PDT 2019 |
2 | From: Eric Dumazet <edumazet@google.com> | |
3 | Date: Thu, 7 Mar 2019 09:36:33 -0800 | |
4 | Subject: net/hsr: fix possible crash in add_timer() | |
5 | ||
6 | From: Eric Dumazet <edumazet@google.com> | |
7 | ||
8 | [ Upstream commit 1e027960edfaa6a43f9ca31081729b716598112b ] | |
9 | ||
10 | syzbot found another add_timer() issue, this time in net/hsr [1] | |
11 | ||
12 | Let's use mod_timer() which is safe. | |
13 | ||
14 | [1] | |
15 | kernel BUG at kernel/time/timer.c:1136! | |
16 | invalid opcode: 0000 [#1] PREEMPT SMP KASAN | |
17 | CPU: 0 PID: 15909 Comm: syz-executor.3 Not tainted 5.0.0+ #97 | |
18 | Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 | |
19 | kobject: 'loop2' (00000000f5629718): kobject_uevent_env | |
20 | RIP: 0010:add_timer kernel/time/timer.c:1136 [inline] | |
21 | RIP: 0010:add_timer+0x654/0xbe0 kernel/time/timer.c:1134 | |
22 | Code: 0f 94 c5 31 ff 44 89 ee e8 09 61 0f 00 45 84 ed 0f 84 77 fd ff ff e8 bb 5f 0f 00 e8 07 10 a0 ff e9 68 fd ff ff e8 ac 5f 0f 00 <0f> 0b e8 a5 5f 0f 00 0f 0b e8 9e 5f 0f 00 4c 89 b5 58 ff ff ff e9 | |
23 | RSP: 0018:ffff8880656eeca0 EFLAGS: 00010246 | |
24 | kobject: 'loop2' (00000000f5629718): fill_kobj_path: path = '/devices/virtual/block/loop2' | |
25 | RAX: 0000000000040000 RBX: 1ffff1100caddd9a RCX: ffffc9000c436000 | |
26 | RDX: 0000000000040000 RSI: ffffffff816056c4 RDI: ffff88806a2f6cc8 | |
27 | RBP: ffff8880656eed58 R08: ffff888067f4a300 R09: ffff888067f4abc8 | |
28 | R10: 0000000000000000 R11: 0000000000000000 R12: ffff88806a2f6cc0 | |
29 | R13: dffffc0000000000 R14: 0000000000000001 R15: ffff8880656eed30 | |
30 | FS: 00007fc2019bf700(0000) GS:ffff8880ae800000(0000) knlGS:0000000000000000 | |
31 | CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 | |
32 | CR2: 0000000000738000 CR3: 0000000067e8e000 CR4: 00000000001406f0 | |
33 | DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 | |
34 | DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 | |
35 | Call Trace: | |
36 | hsr_check_announce net/hsr/hsr_device.c:99 [inline] | |
37 | hsr_check_carrier_and_operstate+0x567/0x6f0 net/hsr/hsr_device.c:120 | |
38 | hsr_netdev_notify+0x297/0xa00 net/hsr/hsr_main.c:51 | |
39 | notifier_call_chain+0xc7/0x240 kernel/notifier.c:93 | |
40 | __raw_notifier_call_chain kernel/notifier.c:394 [inline] | |
41 | raw_notifier_call_chain+0x2e/0x40 kernel/notifier.c:401 | |
42 | call_netdevice_notifiers_info+0x3f/0x90 net/core/dev.c:1739 | |
43 | call_netdevice_notifiers_extack net/core/dev.c:1751 [inline] | |
44 | call_netdevice_notifiers net/core/dev.c:1765 [inline] | |
45 | dev_open net/core/dev.c:1436 [inline] | |
46 | dev_open+0x143/0x160 net/core/dev.c:1424 | |
47 | team_port_add drivers/net/team/team.c:1203 [inline] | |
48 | team_add_slave+0xa07/0x15d0 drivers/net/team/team.c:1933 | |
49 | do_set_master net/core/rtnetlink.c:2358 [inline] | |
50 | do_set_master+0x1d4/0x230 net/core/rtnetlink.c:2332 | |
51 | do_setlink+0x966/0x3510 net/core/rtnetlink.c:2493 | |
52 | rtnl_setlink+0x271/0x3b0 net/core/rtnetlink.c:2747 | |
53 | rtnetlink_rcv_msg+0x465/0xb00 net/core/rtnetlink.c:5192 | |
54 | netlink_rcv_skb+0x17a/0x460 net/netlink/af_netlink.c:2485 | |
55 | rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5210 | |
56 | netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline] | |
57 | netlink_unicast+0x536/0x720 net/netlink/af_netlink.c:1336 | |
58 | netlink_sendmsg+0x8ae/0xd70 net/netlink/af_netlink.c:1925 | |
59 | sock_sendmsg_nosec net/socket.c:622 [inline] | |
60 | sock_sendmsg+0xdd/0x130 net/socket.c:632 | |
61 | sock_write_iter+0x27c/0x3e0 net/socket.c:923 | |
62 | call_write_iter include/linux/fs.h:1869 [inline] | |
63 | do_iter_readv_writev+0x5e0/0x8e0 fs/read_write.c:680 | |
64 | do_iter_write fs/read_write.c:956 [inline] | |
65 | do_iter_write+0x184/0x610 fs/read_write.c:937 | |
66 | vfs_writev+0x1b3/0x2f0 fs/read_write.c:1001 | |
67 | do_writev+0xf6/0x290 fs/read_write.c:1036 | |
68 | __do_sys_writev fs/read_write.c:1109 [inline] | |
69 | __se_sys_writev fs/read_write.c:1106 [inline] | |
70 | __x64_sys_writev+0x75/0xb0 fs/read_write.c:1106 | |
71 | do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290 | |
72 | entry_SYSCALL_64_after_hwframe+0x49/0xbe | |
73 | RIP: 0033:0x457f29 | |
74 | Code: ad b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b8 fb ff c3 66 2e 0f 1f 84 00 00 00 00 | |
75 | RSP: 002b:00007fc2019bec78 EFLAGS: 00000246 ORIG_RAX: 0000000000000014 | |
76 | RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457f29 | |
77 | RDX: 0000000000000001 RSI: 00000000200000c0 RDI: 0000000000000003 | |
78 | RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000 | |
79 | R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc2019bf6d4 | |
80 | R13: 00000000004c4a60 R14: 00000000004dd218 R15: 00000000ffffffff | |
81 | ||
82 | Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)") | |
83 | Signed-off-by: Eric Dumazet <edumazet@google.com> | |
84 | Reported-by: syzbot <syzkaller@googlegroups.com> | |
85 | Cc: Arvid Brodin <arvid.brodin@alten.se> | |
86 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
87 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
88 | --- | |
89 | net/hsr/hsr_device.c | 14 ++++++-------- | |
90 | 1 file changed, 6 insertions(+), 8 deletions(-) | |
91 | ||
92 | --- a/net/hsr/hsr_device.c | |
93 | +++ b/net/hsr/hsr_device.c | |
94 | @@ -94,9 +94,8 @@ static void hsr_check_announce(struct ne | |
95 | && (old_operstate != IF_OPER_UP)) { | |
96 | /* Went up */ | |
97 | hsr->announce_count = 0; | |
98 | - hsr->announce_timer.expires = jiffies + | |
99 | - msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL); | |
100 | - add_timer(&hsr->announce_timer); | |
101 | + mod_timer(&hsr->announce_timer, | |
102 | + jiffies + msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL)); | |
103 | } | |
104 | ||
105 | if ((hsr_dev->operstate != IF_OPER_UP) && (old_operstate == IF_OPER_UP)) | |
106 | @@ -331,6 +330,7 @@ static void hsr_announce(unsigned long d | |
107 | { | |
108 | struct hsr_priv *hsr; | |
109 | struct hsr_port *master; | |
110 | + unsigned long interval; | |
111 | ||
112 | hsr = (struct hsr_priv *) data; | |
113 | ||
114 | @@ -342,18 +342,16 @@ static void hsr_announce(unsigned long d | |
115 | hsr->protVersion); | |
116 | hsr->announce_count++; | |
117 | ||
118 | - hsr->announce_timer.expires = jiffies + | |
119 | - msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL); | |
120 | + interval = msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL); | |
121 | } else { | |
122 | send_hsr_supervision_frame(master, HSR_TLV_LIFE_CHECK, | |
123 | hsr->protVersion); | |
124 | ||
125 | - hsr->announce_timer.expires = jiffies + | |
126 | - msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); | |
127 | + interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); | |
128 | } | |
129 | ||
130 | if (is_admin_up(master->dev)) | |
131 | - add_timer(&hsr->announce_timer); | |
132 | + mod_timer(&hsr->announce_timer, jiffies + interval); | |
133 | ||
134 | rcu_read_unlock(); | |
135 | } |