[Devel] [PATCH rh7] ve: Prevent iteration with NULL dev in device_destroy_namespace()
Kirill Tkhai
ktkhai at odin.com
Tue May 5 10:00:11 PDT 2015
We must check class_find_device() return value before we call namespace method.
Otherwise, we may pass NULL as device in ve_namespace like in below:
[ 4.455518] BUG: unable to handle kernel NULL pointer dereference at 0000000000000278
[ 4.456336] IP: [<ffffffff81233caa>] ve_namespace+0xa/0x40
[ 4.456336] PGD 0
[ 4.456336] Oops: 0000 [#1] SMP
[ 4.456336] Modules linked in:
[ 4.456336] CPU: 1 PID: 1 Comm: swapper/0 ve: 0 Not tainted 3.10.0-123.1.2.el7.ovz.4.8.x86_64 #1 ovz.4.8
[ 4.456336] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M., BIOS SDBLI944.86P 05/08/2007
[ 4.456336] task: ffff8800777e0000 ti: ffff8800777e8000 task.ti: ffff8800777e8000
[ 4.456336] RIP: 0010:[<ffffffff81233caa>] [<ffffffff81233caa>] ve_namespace+0xa/0x40
[ 4.456336] RSP: 0000:ffff8800777e99c8 EFLAGS: 00010286
[ 4.456336] RAX: ffffffff81233ca0 RBX: 0000000000000000 RCX: 0000000000000000
[ 4.456336] RDX: 000000000000091e RSI: ffff8800777e99e4 RDI: 0000000000000000
[ 4.456336] RBP: ffff8800777e99d0 R08: 0000000000000000 R09: 0000000000000004
[ 4.456336] R10: 00000000001c2000 R11: 0000000000000000 R12: ffffffff81960d60
[ 4.456336] R13: 0000000000000000 R14: ffffffff819656a0 R15: ffffffff81991380
[ 4.456336] FS: 0000000000000000(0000) GS:ffff88007a880000(0000) knlGS:0000000000000000
[ 4.456336] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 4.456336] CR2: 0000000000000278 CR3: 00000000018ae000 CR4: 00000000000007e0
[ 4.456336] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 4.456336] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 4.456336] Stack:
[ 4.456336] 0000000000000000 ffff8800777e9a00 ffffffff813a1585 0040004281335d74
[ 4.456336] ffff88006f348000 0000000000000002 ffff88006f36c380 ffff8800777e9a20
[ 4.456336] ffffffff8135b2a2 ffffffff821f7bf0 ffff88006f36c2b0 ffff8800777e9a50
[ 4.456336] Call Trace:
[ 4.456336] [<ffffffff813a1585>] device_destroy_namespace+0x25/0x80
[ 4.456336] [<ffffffff8135b2a2>] tty_unregister_device+0x32/0x60
[ 4.456336] [<ffffffff8137bc4e>] uart_remove_one_port+0x9e/0x130
[ 4.456336] [<ffffffff81380a5e>] serial8250_register_8250_port+0xae/0x390
[ 4.456336] [<ffffffff81385b18>] pciserial_init_ports+0x118/0x210
[ 4.456336] [<ffffffff81385ced>] pciserial_init_one+0xdd/0x200
[ 4.456336] [<ffffffff812d5915>] local_pci_probe+0x45/0xa0
[ 4.456336] [<ffffffff812d6d05>] ? pci_match_device+0xc5/0xd0
[ 4.456336] [<ffffffff812d6e89>] pci_device_probe+0x139/0x150
[ 4.456336] [<ffffffff813a3d37>] driver_probe_device+0x87/0x390
[ 4.456336] [<ffffffff813a4113>] __driver_attach+0x93/0xa0
[ 4.456336] [<ffffffff813a4080>] ? __device_attach+0x40/0x40
[ 4.456336] [<ffffffff813a1ac3>] bus_for_each_dev+0x73/0xc0
[ 4.456336] [<ffffffff813a378e>] driver_attach+0x1e/0x20
[ 4.456336] [<ffffffff813a32e0>] bus_add_driver+0x200/0x2d0
[ 4.456336] [<ffffffff813a4794>] driver_register+0x64/0xf0
[ 4.456336] [<ffffffff812d6b75>] __pci_register_driver+0xa6/0xc0
[ 4.456336] [<ffffffff81a2eadb>] ? early_serial_setup+0x129/0x129
[ 4.456336] [<ffffffff81a2eaf4>] serial_pci_driver_init+0x19/0x1b
[ 4.456336] [<ffffffff810020e2>] do_one_initcall+0xe2/0x190
[ 4.456336] [<ffffffff819ed14f>] kernel_init_freeable+0x17d/0x21c
[ 4.456336] [<ffffffff819ec92b>] ? do_early_param+0x88/0x88
[ 4.456336] [<ffffffff815a8010>] ? rest_init+0x80/0x80
[ 4.456336] [<ffffffff815a801e>] kernel_init+0xe/0x180
[ 4.456336] [<ffffffff815d5f2c>] ret_from_fork+0x7c/0xb0
[ 4.456336] [<ffffffff815a8010>] ? rest_init+0x80/0x80
[ 4.456336] [<ffffffff815a801e>] kernel_init+0xe/0x180
[ 4.456336] [<ffffffff815d5f2c>] ret_from_fork+0x7c/0xb0
[ 4.456336] [<ffffffff815a8010>] ? rest_init+0x80/0x80
[ 4.456336] Code: ff ff ff 66 0f 1f 44 00 00 49 89 45 18 e9 35 ff ff ff 0f 0b 0f 0b 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 53 <48> 83 bf 78 02 00 00 00 48 89 fb 74 11 48 c7 c0 c0 cb 8e 81 5b
0x278 is groups atribute offset in structure device.
The patch fixes the problem and makes the check logic similar to logic in device_destroy().
https://jira.sw.ru/browse/PSBM-33239
Signed-off-by: Kirill Tkhai <ktkhai at odin.com>
---
drivers/base/core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 98e8e3b..6583bec 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1840,12 +1840,14 @@ void device_destroy_namespace(struct class *class, dev_t devt, void *ns)
{
struct device *dev = NULL;
- do {
+ for (;;) {
dev = class_find_device(class, dev, &devt, __match_devt);
+ if (!dev)
+ break;
if (!class->namespace ||
(class->namespace(dev) == ns))
break;
- } while (dev);
+ }
if (dev) {
put_device(dev);
More information about the Devel
mailing list