diff options
author | Cong Wang <xiyou.wangcong@gmail.com> | 2019-07-03 17:21:14 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-05 15:22:27 -0700 |
commit | edf070a0fb45ac845f534baf172fbadbeb5048c6 (patch) | |
tree | f669d881677f8592fa59b470202e234c65e2ba1f /net/hsr | |
parent | b9a1e627405d68d475a3c1f35e685ccfb5bbe668 (diff) | |
download | linux-edf070a0fb45ac845f534baf172fbadbeb5048c6.tar.bz2 |
hsr: fix a NULL pointer deref in hsr_dev_xmit()
hsr_port_get_hsr() could return NULL and kernel
could crash:
BUG: kernel NULL pointer dereference, address: 0000000000000010
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 8000000074b84067 P4D 8000000074b84067 PUD 7057d067 PMD 0
Oops: 0000 [#1] SMP PTI
CPU: 0 PID: 754 Comm: a.out Not tainted 5.2.0-rc6+ #718
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014
RIP: 0010:hsr_dev_xmit+0x20/0x31
Code: 48 8b 1b eb e0 5b 5d 41 5c c3 66 66 66 66 90 55 48 89 fd 48 8d be 40 0b 00 00 be 04 00 00 00 e8 ee f2 ff ff 48 89 ef 48 89 c6 <48> 8b 40 10 48 89 45 10 e8 6c 1b 00 00 31 c0 5d c3 66 66 66 66 90
RSP: 0018:ffffb5b400003c48 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff9821b4509a88 RCX: 0000000000000000
RDX: ffff9821b4509a88 RSI: 0000000000000000 RDI: ffff9821bc3fc7c0
RBP: ffff9821bc3fc7c0 R08: 0000000000000000 R09: 00000000000c2019
R10: 0000000000000000 R11: 0000000000000002 R12: ffff9821bc3fc7c0
R13: ffff9821b4509a88 R14: 0000000000000000 R15: 000000000000006e
FS: 00007fee112a1800(0000) GS:ffff9821bd800000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000010 CR3: 000000006e9ce000 CR4: 00000000000406f0
Call Trace:
<IRQ>
netdev_start_xmit+0x1b/0x38
dev_hard_start_xmit+0x121/0x21e
? validate_xmit_skb.isra.0+0x19/0x1e3
__dev_queue_xmit+0x74c/0x823
? lockdep_hardirqs_on+0x12b/0x17d
ip6_finish_output2+0x3d3/0x42c
? ip6_mtu+0x55/0x5c
? mld_sendpack+0x191/0x229
mld_sendpack+0x191/0x229
mld_ifc_timer_expire+0x1f7/0x230
? mld_dad_timer_expire+0x58/0x58
call_timer_fn+0x12e/0x273
__run_timers.part.0+0x174/0x1b5
? mld_dad_timer_expire+0x58/0x58
? sched_clock_cpu+0x10/0xad
? mark_lock+0x26/0x1f2
? __lock_is_held+0x40/0x71
run_timer_softirq+0x26/0x48
__do_softirq+0x1af/0x392
irq_exit+0x53/0xa2
smp_apic_timer_interrupt+0x1c4/0x1d9
apic_timer_interrupt+0xf/0x20
</IRQ>
Cc: Arvid Brodin <arvid.brodin@alten.se>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/hsr')
-rw-r--r-- | net/hsr/hsr_device.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 4ea7d54a8262..f0f9b493c47b 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -227,9 +227,13 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) struct hsr_port *master; master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); - skb->dev = master->dev; - hsr_forward_skb(skb, master); - + if (master) { + skb->dev = master->dev; + hsr_forward_skb(skb, master); + } else { + atomic_long_inc(&dev->tx_dropped); + dev_kfree_skb_any(skb); + } return NETDEV_TX_OK; } |