Skip to content

Commit 00c1a53

Browse files
Dotan BarakMukesh Kacker
authored andcommitted
ib_core: fix NULL pointer dereference
If there was a failure in the initial fill of the Pkey/GID cache, and some other ULP/module will try to query a Pkey/GID, the NULL pointer will be dereferenced, thing that will lead to the following kernel panic: BUG: unable to handle kernel NULL pointer dereference at 0000000000000058 IP: [<ffffffff814ef21f>] _spin_lock_irqsave+0x1f/0x40 PGD 37b49067 PUD becb3067 PMD 0 Oops: 0002 [#1] SMP last sysfs file: /sys/module/mlx4_core/initstate CPU 1 Modules linked in: mlx4_ib(+)(U) ib_sa(U) ib_mad(U) ib_core(U) mlx4_en(U) mlx4_core(U) memtrack(U) netconsole configfs nfs fscache nfsd lockd nfs_acl auth_rpcgss exportfs autofs4 sunrpc ipv6 knem(U) microcode virtio_balloon virtio_net snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc i2c_piix4 i2c_core ext3 jbd mbcache virtio_blk virtio_pci virtio_ring virtio pata_acpi ata_generic ata_piix dm_mirror dm_region_hash dm_log dm_mod [last unloaded: memtrack] Pid: 20715, comm: modprobe Not tainted 2.6.32-220.el6.x86_64 #1 Red Hat KVM RIP: 0010:[<ffffffff814ef21f>] [<ffffffff814ef21f>] _spin_lock_irqsave+0x1f/0x40 RSP: 0018:ffff8800bc331d08 EFLAGS: 00010002 RAX: 0000000000010000 RBX: ffff8800bec00088 RCX: 0000000000000000 RDX: 0000000000000202 RSI: 0000000000000046 RDI: 0000000000000058 RBP: ffff8800bc331d08 R08: 0000000000000000 R09: ffff88011bde8050 R10: ffff8800bc3317d8 R11: 0000000000000002 R12: ffff8800b9520000 R13: ffff8800bec00000 R14: 0000000000000000 R15: ffff8800bec02c00 FS: 00007f2f07fcd700(0000) GS:ffff880028300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000058 CR3: 00000000bb708000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process modprobe (pid: 20715, threadinfo ffff8800bc330000, task ffff8801185e0b40) Stack: ffff8800bc331d28 ffffffffa0244ee5 ffff8800bec00000 ffff8800b9520000 <0> ffff8800bc331d68 ffffffffa0246f96 0000000000000370 ffffffffa0359560 <0> ffffffffa024fde0 ffff8800b9520000 ffff8800bec00000 ffff8800bcf36080 Call Trace: [<ffffffffa0244ee5>] ib_unregister_event_handler+0x25/0x50 [ib_core] [<ffffffffa0246f96>] ib_cache_cleanup_one+0x26/0x1b0 [ib_core] [<ffffffffa02450ce>] ib_unregister_device+0x4e/0x1a0 [ib_core] [<ffffffffa035fee6>] ? mlx4_ib_mad_init+0xa6/0x170 [mlx4_ib] [<ffffffffa0366721>] mlx4_ib_add+0x621/0xb80 [mlx4_ib] [<ffffffffa0456e73>] mlx4_add_device+0x73/0x1d0 [mlx4_core] [<ffffffffa04570db>] mlx4_register_interface+0x7b/0x100 [mlx4_core] [<ffffffffa013112a>] mlx4_ib_init+0x12a/0x188 [mlx4_ib] [<ffffffffa0131000>] ? mlx4_ib_init+0x0/0x188 [mlx4_ib] [<ffffffff8100204c>] do_one_initcall+0x3c/0x1d0 [<ffffffff810af641>] sys_init_module+0xe1/0x250 [<ffffffff8100b0f2>] system_call_fastpath+0x16/0x1b Code: c9 c3 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 0f 1f 44 00 00 9c 58 0f 1f 44 00 00 48 89 c2 fa 66 0f 1f 44 00 00 b8 00 00 01 00 <f0> 0f c1 07 0f b7 c8 c1 e8 10 39 c1 74 0e f3 90 0f 1f 44 00 00 RIP [<ffffffff814ef21f>] _spin_lock_irqsave+0x1f/0x40 RSP <ffff8800bc331d08> CR2: 0000000000000058 ---[ end trace 4cc9b3e738027b7c ]--- Kernel panic - not syncing: Fatal exception Pid: 20715, comm: modprobe Tainted: G D ---------------- 2.6.32-220.el6.x86_64 #1 Call Trace: [<ffffffff814ec341>] ? panic+0x78/0x143 [<ffffffff814f04d4>] ? oops_end+0xe4/0x100 [<ffffffff8104230b>] ? no_context+0xfb/0x260 [<ffffffffa001a62d>] ? start_xmit+0x5d/0x1d0 [virtio_net] [<ffffffff81042595>] ? __bad_area_nosemaphore+0x125/0x1e0 [<ffffffff810426be>] ? bad_area+0x4e/0x60 [<ffffffff81042dc3>] ? __do_page_fault+0x3c3/0x480 [<ffffffffa03d737d>] ? write_msg+0xfd/0x110 [netconsole] [<ffffffff81069d15>] ? __call_console_drivers+0x75/0x90 [<ffffffff8109694f>] ? up+0x2f/0x50 [<ffffffff81069d7a>] ? _call_console_drivers+0x4a/0x80 [<ffffffff814f248e>] ? do_page_fault+0x3e/0xa0 [<ffffffff814ef845>] ? page_fault+0x25/0x30 [<ffffffff814ef21f>] ? _spin_lock_irqsave+0x1f/0x40 [<ffffffffa0244ee5>] ? ib_unregister_event_handler+0x25/0x50 [ib_core] [<ffffffffa0246f96>] ? ib_cache_cleanup_one+0x26/0x1b0 [ib_core] [<ffffffffa02450ce>] ? ib_unregister_device+0x4e/0x1a0 [ib_core] [<ffffffffa035fee6>] ? mlx4_ib_mad_init+0xa6/0x170 [mlx4_ib] [<ffffffffa0366721>] ? mlx4_ib_add+0x621/0xb80 [mlx4_ib] [<ffffffffa0456e73>] ? mlx4_add_device+0x73/0x1d0 [mlx4_core] [<ffffffffa04570db>] ? mlx4_register_interface+0x7b/0x100 [mlx4_core] [<ffffffffa013112a>] ? mlx4_ib_init+0x12a/0x188 [mlx4_ib] [<ffffffffa0131000>] ? mlx4_ib_init+0x0/0x188 [mlx4_ib] [<ffffffff8100204c>] ? do_one_initcall+0x3c/0x1d0 [<ffffffff810af641>] ? sys_init_module+0xe1/0x250 [<ffffffff8100b0f2>] ? system_call_fastpath+0x16/0x1b Signed-off-by: Dotan Barak <[email protected]> Reviewed-by: Eli Cohen <[email protected]> (Ported from Mellanox OFED 2.4) Signed-off-by: Mukesh Kacker <[email protected]>
1 parent b1a086c commit 00c1a53

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

drivers/infiniband/core/cache.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,21 @@ int ib_get_cached_gid(struct ib_device *device,
7676
{
7777
struct ib_gid_cache *cache;
7878
unsigned long flags;
79-
int ret = 0;
79+
int ret = -EINVAL;
8080

8181
if (port_num < start_port(device) || port_num > end_port(device))
8282
return -EINVAL;
8383

8484
read_lock_irqsave(&device->cache.lock, flags);
8585

86-
cache = device->cache.gid_cache[port_num - start_port(device)];
86+
if (device->cache.gid_cache) {
87+
cache = device->cache.gid_cache[port_num - start_port(device)];
8788

88-
if (index < 0 || index >= cache->table_len)
89-
ret = -EINVAL;
90-
else
91-
*gid = cache->table[index];
89+
if (cache && index >= 0 && index < cache->table_len) {
90+
*gid = cache->table[index];
91+
ret = 0;
92+
}
93+
}
9294

9395
read_unlock_irqrestore(&device->cache.lock, flags);
9496

@@ -138,19 +140,21 @@ int ib_get_cached_pkey(struct ib_device *device,
138140
{
139141
struct ib_pkey_cache *cache;
140142
unsigned long flags;
141-
int ret = 0;
143+
int ret = -EINVAL;
142144

143145
if (port_num < start_port(device) || port_num > end_port(device))
144146
return -EINVAL;
145147

146148
read_lock_irqsave(&device->cache.lock, flags);
147149

148-
cache = device->cache.pkey_cache[port_num - start_port(device)];
150+
if (device->cache.pkey_cache) {
151+
cache = device->cache.pkey_cache[port_num - start_port(device)];
149152

150-
if (index < 0 || index >= cache->table_len)
151-
ret = -EINVAL;
152-
else
153-
*pkey = cache->table[index];
153+
if (cache && index >= 0 && index < cache->table_len) {
154+
*pkey = cache->table[index];
155+
ret = 0;
156+
}
157+
}
154158

155159
read_unlock_irqrestore(&device->cache.lock, flags);
156160

@@ -236,13 +240,16 @@ int ib_get_cached_lmc(struct ib_device *device,
236240
u8 *lmc)
237241
{
238242
unsigned long flags;
239-
int ret = 0;
243+
int ret = -EINVAL;
240244

241245
if (port_num < start_port(device) || port_num > end_port(device))
242246
return -EINVAL;
243247

244248
read_lock_irqsave(&device->cache.lock, flags);
245-
*lmc = device->cache.lmc_cache[port_num - start_port(device)];
249+
if (device->cache.lmc_cache) {
250+
*lmc = device->cache.lmc_cache[port_num - start_port(device)];
251+
ret = 0;
252+
}
246253
read_unlock_irqrestore(&device->cache.lock, flags);
247254

248255
return ret;
@@ -403,12 +410,19 @@ static void ib_cache_setup_one(struct ib_device *device)
403410
kfree(device->cache.pkey_cache);
404411
kfree(device->cache.gid_cache);
405412
kfree(device->cache.lmc_cache);
413+
device->cache.pkey_cache = NULL;
414+
device->cache.gid_cache = NULL;
415+
device->cache.lmc_cache = NULL;
406416
}
407417

408418
static void ib_cache_cleanup_one(struct ib_device *device)
409419
{
410420
int p;
411421

422+
if (!(device->cache.pkey_cache && device->cache.gid_cache &&
423+
device->cache.lmc_cache))
424+
return;
425+
412426
ib_unregister_event_handler(&device->cache.event_handler);
413427
flush_workqueue(ib_wq);
414428

0 commit comments

Comments
 (0)