pppoe_connect() mustn't touch the padt_work field of pppoe sockets
because that work could be already pending.
[ 21.473147] BUG: unable to handle kernel NULL pointer dereference at
00000004
[ 21.474523] IP: [<
c1043177>] process_one_work+0x29/0x31c
[ 21.475164] *pde =
00000000
[ 21.475513] Oops: 0000 [#1] SMP
[ 21.475910] Modules linked in: pppoe pppox ppp_generic slhc crc32c_intel aesni_intel virtio_net xts aes_i586 lrw gf128mul ablk_helper cryptd evdev acpi_cpufreq processor serio_raw button ext4 crc16 mbcache jbd2 virtio_blk virtio_pci virtio_ring virtio
[ 21.476168] CPU: 2 PID: 164 Comm: kworker/2:2 Not tainted 4.4.0-rc1 #1
[ 21.476168] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Debian-1.8.2-1 04/01/2014
[ 21.476168] task:
f5f83c00 ti:
f5e28000 task.ti:
f5e28000
[ 21.476168] EIP: 0060:[<
c1043177>] EFLAGS:
00010046 CPU: 2
[ 21.476168] EIP is at process_one_work+0x29/0x31c
[ 21.484082] EAX:
00000000 EBX:
f678b2a0 ECX:
00000004 EDX:
00000000
[ 21.484082] ESI:
f6c69940 EDI:
f5e29ef0 EBP:
f5e29f0c ESP:
f5e29edc
[ 21.484082] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[ 21.484082] CR0:
80050033 CR2:
000000a4 CR3:
317ad000 CR4:
00040690
[ 21.484082] Stack:
[ 21.484082]
00000000 f6c69950 00000000 f6c69940 c0042338 f5e29f0c c1327945 00000000
[ 21.484082]
00000008 f678b2a0 f6c69940 f678b2b8 f5e29f30 c1043984 f5f83c00 f6c69970
[ 21.484082]
f678b2a0 c10437d3 f6775e80 f678b2a0 c10437d3 f5e29fac c1047059 f5e29f74
[ 21.484082] Call Trace:
[ 21.484082] [<
c1327945>] ? _raw_spin_lock_irq+0x28/0x30
[ 21.484082] [<
c1043984>] worker_thread+0x1b1/0x244
[ 21.484082] [<
c10437d3>] ? rescuer_thread+0x229/0x229
[ 21.484082] [<
c10437d3>] ? rescuer_thread+0x229/0x229
[ 21.484082] [<
c1047059>] kthread+0x8f/0x94
[ 21.484082] [<
c1327a32>] ? _raw_spin_unlock_irq+0x22/0x26
[ 21.484082] [<
c1327ee9>] ret_from_kernel_thread+0x21/0x38
[ 21.484082] [<
c1046fca>] ? kthread_parkme+0x19/0x19
[ 21.496082] Code: 5d c3 55 89 e5 57 56 53 89 c3 83 ec 24 89 d0 89 55 e0 8d 7d e4 e8 6c d8 ff ff b9 04 00 00 00 89 45 d8 8b 43 24 89 45 dc 8b 45 d8 <8b> 40 04 8b 80 e0 00 00 00 c1 e8 05 24 01 88 45 d7 8b 45 e0 8d
[ 21.496082] EIP: [<
c1043177>] process_one_work+0x29/0x31c SS:ESP 0068:
f5e29edc
[ 21.496082] CR2:
0000000000000004
[ 21.496082] ---[ end trace
e362cc9cf10dae89 ]---
Reported-by: Andrew <nitr0@seti.kr.ua>
Fixes:
287f3a943fef ("pppoe: Use workqueue to die properly when a PADT is received")
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
sk->sk_family = PF_PPPOX;
sk->sk_protocol = PX_PROTO_OE;
+ INIT_WORK(&pppox_sk(sk)->proto.pppoe.padt_work,
+ pppoe_unbind_sock_work);
+
return 0;
}
lock_sock(sk);
- INIT_WORK(&po->proto.pppoe.padt_work, pppoe_unbind_sock_work);
-
error = -EINVAL;
if (sp->sa_protocol != PX_PROTO_OE)
goto end;
po->pppoe_dev = NULL;
}
- memset(sk_pppox(po) + 1, 0,
- sizeof(struct pppox_sock) - sizeof(struct sock));
+ po->pppoe_ifindex = 0;
+ memset(&po->pppoe_pa, 0, sizeof(po->pppoe_pa));
+ memset(&po->pppoe_relay, 0, sizeof(po->pppoe_relay));
+ memset(&po->chan, 0, sizeof(po->chan));
+ po->next = NULL;
+ po->num = 0;
+
sk->sk_state = PPPOX_NONE;
}