linux/drivers
Seymour, Shane M 845a83bb5a st: null pointer dereference panic caused by use after kref_put by st_open
[ Upstream commit e7ac6c6666 ]

Two SLES11 SP3 servers encountered similar crashes simultaneously
following some kind of SAN/tape target issue:

...
qla2xxx [0000:81:00.0]-801c:3: Abort command issued nexus=3:0:2 --  1 2002.
qla2xxx [0000:81:00.0]-801c:3: Abort command issued nexus=3:0:2 --  1 2002.
qla2xxx [0000:81:00.0]-8009:3: DEVICE RESET ISSUED nexus=3:0:2 cmd=ffff882f89c2c7c0.
qla2xxx [0000:81:00.0]-800c:3: do_reset failed for cmd=ffff882f89c2c7c0.
qla2xxx [0000:81:00.0]-800f:3: DEVICE RESET FAILED: Task management failed nexus=3:0:2 cmd=ffff882f89c2c7c0.
qla2xxx [0000:81:00.0]-8009:3: TARGET RESET ISSUED nexus=3:0:2 cmd=ffff882f89c2c7c0.
qla2xxx [0000:81:00.0]-800c:3: do_reset failed for cmd=ffff882f89c2c7c0.
qla2xxx [0000:81:00.0]-800f:3: TARGET RESET FAILED: Task management failed nexus=3:0:2 cmd=ffff882f89c2c7c0.
qla2xxx [0000:81:00.0]-8012:3: BUS RESET ISSUED nexus=3:0:2.
qla2xxx [0000:81:00.0]-802b:3: BUS RESET SUCCEEDED nexus=3:0:2.
qla2xxx [0000:81:00.0]-505f:3: Link is operational (8 Gbps).
qla2xxx [0000:81:00.0]-8018:3: ADAPTER RESET ISSUED nexus=3:0:2.
qla2xxx [0000:81:00.0]-00af:3: Performing ISP error recovery - ha=ffff88bf04d18000.
 rport-3:0-0: blocked FC remote port time out: removing target and saving binding
qla2xxx [0000:81:00.0]-505f:3: Link is operational (8 Gbps).
qla2xxx [0000:81:00.0]-8017:3: ADAPTER RESET SUCCEEDED nexus=3:0:2.
 rport-2:0-0: blocked FC remote port time out: removing target and saving binding
sg_rq_end_io: device detached
BUG: unable to handle kernel NULL pointer dereference at 00000000000002a8
IP: [<ffffffff8133b268>] __pm_runtime_idle+0x28/0x90
PGD 7e6586f067 PUD 7e5af06067 PMD 0 [1739975.390354] Oops: 0002 [#1] SMP
CPU 0
...
Supported: No, Proprietary modules are loaded [1739975.390463]
Pid: 27965, comm: ABCD Tainted: PF           X 3.0.101-0.29-default #1 HP ProLiant DL580 Gen8
RIP: 0010:[<ffffffff8133b268>]  [<ffffffff8133b268>] __pm_runtime_idle+0x28/0x90
RSP: 0018:ffff8839dc1e7c68  EFLAGS: 00010202
RAX: 0000000000000000 RBX: ffff883f0592fc00 RCX: 0000000000000090
RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000138
RBP: 0000000000000138 R08: 0000000000000010 R09: ffffffff81bd39d0
R10: 00000000000009c0 R11: ffffffff81025790 R12: 0000000000000001
R13: ffff883022212b80 R14: 0000000000000004 R15: ffff883022212b80
FS:  00007f8e54560720(0000) GS:ffff88407f800000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00000000000002a8 CR3: 0000007e6ced6000 CR4: 00000000001407f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process ABCD (pid: 27965, threadinfo ffff8839dc1e6000, task ffff883592e0c640)
Stack:
 ffff883f0592fc00 00000000fffffffa 0000000000000001 ffff883022212b80
 ffff883eff772400 ffffffffa03fa309 0000000000000000 0000000000000000
 ffffffffa04003a0 ffff883f063196c0 ffff887f0379a930 ffffffff8115ea1e
Call Trace:
 [<ffffffffa03fa309>] st_open+0x129/0x240 [st]
 [<ffffffff8115ea1e>] chrdev_open+0x13e/0x200
 [<ffffffff811588a8>] __dentry_open+0x198/0x310
 [<ffffffff81167d74>] do_last+0x1f4/0x800
 [<ffffffff81168fe9>] path_openat+0xd9/0x420
 [<ffffffff8116946c>] do_filp_open+0x4c/0xc0
 [<ffffffff8115a00f>] do_sys_open+0x17f/0x250
 [<ffffffff81468d92>] system_call_fastpath+0x16/0x1b
 [<00007f8e4f617fd0>] 0x7f8e4f617fcf
Code: eb d3 90 48 83 ec 28 40 f6 c6 04 48 89 6c 24 08 4c 89 74 24 20 48 89 fd 48 89 1c 24 4c 89 64 24 10 41 89 f6 4c 89 6c 24 18 74 11 <f0> ff 8f 70 01 00 00 0f 94 c0 45 31 ed 84 c0 74 2b 4c 8d a5 a0
RIP  [<ffffffff8133b268>] __pm_runtime_idle+0x28/0x90
 RSP <ffff8839dc1e7c68>
CR2: 00000000000002a8

Analysis reveals the cause of the crash to be due to STp->device
being NULL. The pointer was NULLed via scsi_tape_put(STp) when it
calls scsi_tape_release(). In st_open() we jump to err_out after
scsi_block_when_processing_errors() completes and returns the
device as offline (sdev_state was SDEV_DEL):

1180 /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
1181    module count. */
1182 static int st_open(struct inode *inode, struct file *filp)
1183 {
1184         int i, retval = (-EIO);
1185         int resumed = 0;
1186         struct scsi_tape *STp;
1187         struct st_partstat *STps;
1188         int dev = TAPE_NR(inode);
1189         char *name;
...
1217         if (scsi_autopm_get_device(STp->device) < 0) {
1218                 retval = -EIO;
1219                 goto err_out;
1220         }
1221         resumed = 1;
1222         if (!scsi_block_when_processing_errors(STp->device)) {
1223                 retval = (-ENXIO);
1224                 goto err_out;
1225         }
...
1264  err_out:
1265         normalize_buffer(STp->buffer);
1266         spin_lock(&st_use_lock);
1267         STp->in_use = 0;
1268         spin_unlock(&st_use_lock);
1269         scsi_tape_put(STp); <-- STp->device = 0 after this
1270         if (resumed)
1271                 scsi_autopm_put_device(STp->device);
1272         return retval;

The ref count for the struct scsi_tape had already been reduced
to 1 when the .remove method of the st module had been called.
The kref_put() in scsi_tape_put() caused scsi_tape_release()
to be called:

0266 static void scsi_tape_put(struct scsi_tape *STp)
0267 {
0268         struct scsi_device *sdev = STp->device;
0269
0270         mutex_lock(&st_ref_mutex);
0271         kref_put(&STp->kref, scsi_tape_release); <-- calls this
0272         scsi_device_put(sdev);
0273         mutex_unlock(&st_ref_mutex);
0274 }

In scsi_tape_release() the struct scsi_device in the struct
scsi_tape gets set to NULL:

4273 static void scsi_tape_release(struct kref *kref)
4274 {
4275         struct scsi_tape *tpnt = to_scsi_tape(kref);
4276         struct gendisk *disk = tpnt->disk;
4277
4278         tpnt->device = NULL; <<<---- where the dev is nulled
4279
4280         if (tpnt->buffer) {
4281                 normalize_buffer(tpnt->buffer);
4282                 kfree(tpnt->buffer->reserved_pages);
4283                 kfree(tpnt->buffer);
4284         }
4285
4286         disk->private_data = NULL;
4287         put_disk(disk);
4288         kfree(tpnt);
4289         return;
4290 }

Although the problem was reported on SLES11.3 the problem appears
in linux-next as well.

The crash is fixed by reordering the code so we no longer access
the struct scsi_tape after the kref_put() is done on it in st_open().

Signed-off-by: Shane Seymour <shane.seymour@hp.com>
Signed-off-by: Darren Lavender <darren.lavender@hp.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.com>
Acked-by: Kai Mäkisara <kai.makisara@kolumbus.fi>
Cc: stable@vger.kernel.org
Signed-off-by: James Bottomley <JBottomley@Odin.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
History 2015-08-27 13:25:43 -04:00
..
accessibility printk: move braille console support into separate braille.[ch] files 2013-07-31 14:41:03 -07:00
acpi ACPI / init: Switch over platform to the ACPI mode later 2015-08-27 13:25:39 -04:00
amba PM / Domains: Move dev_pm_domain_attach|detach() to pm_domain.h 2014-09-30 01:16:44 +02:00
ata libata: force disable trim for SuperSSpeed S238 2015-08-04 14:29:51 -04:00
atm solos-pci: fix error return code 2014-11-23 14:29:44 -05:00
auxdisplay framebuffer: Use fb_<level> 2013-10-29 12:53:07 +02:00
base Fix firmware loader uevent buffer NULL pointer dereference 2015-08-04 14:43:38 -04:00
bcma bcma: add another PCI ID of device with BCM43228 2014-10-23 14:02:06 -04:00
block rbd: fix copyup completion race 2015-08-27 13:25:27 -04:00
bluetooth Bluetooth: ath3k: Add support of 04ca:300d AR3012 device 2015-07-03 23:02:34 -04:00
bus bus: arm-ccn: Fix node->XP config conversion 2015-07-03 23:02:13 -04:00
cdrom block,scsi: fixup blk_get_request dead queue scenarios 2014-08-28 10:03:46 -06:00
char hwmon: (dell-smm) Blacklist Dell Studio XPS 8100 2015-08-27 13:25:30 -04:00
clk clk: keystone: add support for post divider register for main pll 2015-08-22 14:05:31 -04:00
clocksource clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier 2015-07-05 10:12:52 -04:00
connector connector: Use ktime_get_ns() 2014-07-23 10:18:07 -07:00
cpufreq intel_pstate: set BYT MSR with wrmsrl_on_cpu() 2015-07-03 23:02:15 -04:00
cpuidle cpuidle: remove state_count field from struct cpuidle_device 2015-04-24 17:13:56 -04:00
crypto crypto: ixp4xx - Remove bogus BUG_ON on scattered dst buffer 2015-08-27 13:25:27 -04:00
dca dca: convert to idr_alloc() 2013-02-27 19:10:15 -08:00
devfreq PM / devfreq: exynos: Enable building exynos PPMU as module 2014-09-29 20:22:36 +09:00
dio m68k: don't export static inline functions 2009-12-06 11:18:28 +01:00
dma dmaengine: mv_xor: bug fix for racing condition in descriptors cleanup 2015-07-03 23:02:28 -04:00
dma-buf reservation: Remove shadowing local variable 'ret' 2015-03-23 21:02:50 -04:00
edac sb_edac: Fix erroneous bytes->gigabytes conversion 2015-07-13 08:50:04 -04:00
eisa Revert "EISA: Initialize device before its resources" 2014-01-17 14:57:29 -07:00
extcon extcon: gpio: Fix code cleanup 2014-09-22 16:48:47 +09:00
firewire firewire: cdev: prevent kernel stack leaking into ioctl arguments 2014-11-14 12:10:13 +01:00
firmware firmware: dmi_scan: Fix ordering of product_uuid 2015-06-10 13:42:36 -04:00
fmc Merge 3.14-rc5 into char-misc-next 2014-03-02 19:53:09 -08:00
gpio gpio: crystalcove: set IRQCHIP_SKIP_SET_WAKE for the irqchip 2015-07-03 23:02:23 -04:00
gpu drm/dp-mst: Remove debug WARN_ON 2015-08-19 13:17:44 -04:00
hid HID: sony: Add support for the third-party SMK PS3 Bluetooth Remote 2015-06-28 21:23:48 -04:00
hsi HSI changes for the v3.17 series 2014-08-06 20:06:14 -07:00
hv Drivers: hv: vmbus: Don't wait after requesting offers 2015-05-17 19:12:43 -04:00
hwmon hwmon: (mcp3021) Fix broken output scaling 2015-07-05 10:12:56 -04:00
hwspinlock hwspinlock: enable OMAP build for AM33xx, AM43xx & DRA7xx 2014-07-29 11:46:28 +03:00
i2c i2c: at91: fix a race condition when using the DMA controller 2015-07-03 23:02:28 -04:00
ide Merge branch 'for-3.18/drivers' of git://git.kernel.dk/linux-block 2014-10-18 12:12:45 -07:00
idle intel_idle: Broadwell support 2014-08-15 17:06:40 -04:00
iio iio: adc: at91_adc: allow to use full range of startup time 2015-08-04 14:16:40 -04:00
infiniband iser-target: Fix possible deadlock in RDMA_CM connection error 2015-08-04 14:34:34 -04:00
input Input: synaptics - add min/max quirk for Lenovo S540 2015-07-20 21:12:44 -04:00
iommu iommu/amd: Handle large pages correctly in free_pagetable 2015-07-13 08:50:07 -04:00
ipack ipoctal: clear break interrupt as soon as it occurs 2014-09-23 23:26:42 -07:00
irqchip irqchip: sunxi-nmi: Fix off-by-one error in irq iterator 2015-07-03 12:34:47 -04:00
isdn isdn/gigaset: fix usb_gigaset write_cmd result race 2014-10-14 15:05:35 -04:00
leds leds / PM: fix hibernation on arm when gpio-led used with CPU led trigger 2015-07-03 23:02:15 -04:00
lguest x86: Clean up cr4 manipulation 2015-06-28 13:39:27 -04:00
macintosh powerpc: Move via-cuda symbol exports next to function definitions 2014-09-25 23:14:37 +10:00
mailbox Merge branch 'mailbox-for-linus' of git://git.linaro.org/landing-teams/working/fujitsu/integration 2014-10-21 11:21:19 -07:00
mcb mcb: Add support for shared PCI IRQs 2014-05-27 17:38:11 -07:00
md md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies 2015-08-27 13:25:33 -04:00
media [media] media: Fix regression in some more dib0700 based devices 2015-07-03 23:02:17 -04:00
memory AT91 reset, poweroff and ram drivers 2014-08-25 15:35:26 +02:00
memstick memstick: mspro_block: add missing curly braces 2015-05-17 19:12:28 -04:00
message SCSI for-linus on 20141007 2014-10-07 21:29:18 -04:00
mfd mfd: kempld-core: Fix callback return value check 2015-04-16 20:13:19 -04:00
misc mei: me: wait for power gating exit confirmation 2015-07-03 23:02:29 -04:00
mmc mmc: card: Fixup request missing in mmc_blk_issue_rw_rq 2015-08-04 14:35:17 -04:00
mtd mtd: fix: avoid race condition when accessing mtd->usecount 2015-07-03 23:02:14 -04:00
net Revert "can: fix loss of CAN frames in raw_rcv" 2015-08-04 13:32:39 -04:00
nfc NFC: st21nfcb: remove st21nfcb_nci_i2c_disable 2015-07-03 23:02:25 -04:00
ntb ntb: Adding split BAR support for Haswell platforms 2014-10-17 07:08:51 -04:00
nubus kernel/printk: use symbolic defines for console loglevels 2014-06-04 16:54:17 -07:00
of of: return NUMA_NO_NODE from fallback of_node_to_nid() 2015-08-04 14:39:26 -04:00
oprofile drivers/oprofile: Replace __get_cpu_var uses for address calculation 2014-08-26 13:45:46 -04:00
parisc Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2014-10-13 16:23:15 +02:00
parport parport: parport_pc: Implement architecture and device check to cut off false-positives 2014-09-23 23:14:28 -07:00
pci PCI: pciehp: Wait for hotplug command completion where necessary 2015-07-03 23:02:25 -04:00
pcmcia Disable write buffering on Toshiba ToPIC95 2015-07-03 23:02:29 -04:00
phy phy: twl4030-usb: make runtime pm more reliable. 2015-08-20 17:33:10 -04:00
pinctrl pinctrl: mvebu: armada-38x: fix incorrect total number of GPIOs 2015-07-03 23:02:27 -04:00
platform dell-laptop: Fix allocating & freeing SMI buffer page 2015-08-04 14:38:19 -04:00
pnp PNP: replace strnicmp with strncasecmp 2014-10-14 02:18:25 +02:00
power power/reset: at91: fix return value check in at91_reset_platform_probe() 2015-06-10 13:42:45 -04:00
powercap powercap / RAPL: change domain detection message 2014-09-03 01:29:00 +02:00
pps drivers/pps/clients/pps-gpio.c: remove redundant of_match_ptr 2013-11-13 12:09:35 +09:00
ps3 ps3-vuart: don't use PREPARE_WORK 2014-03-07 10:24:48 -05:00
ptp PCI: Remove DEFINE_PCI_DEVICE_TABLE macro use 2014-08-12 12:15:14 -06:00
pwm pwm: Changes for v3.18-rc1 2014-10-21 08:17:43 -07:00
rapidio PCI: Remove DEFINE_PCI_DEVICE_TABLE macro use 2014-08-12 12:15:14 -06:00
ras trace, RAS: Add eMCA trace event interface 2014-06-25 13:26:47 -07:00
regulator regulator: core: fix constraints output buffer 2015-07-03 23:02:25 -04:00
remoteproc remoteproc: da8xx: don't select CMA on no-MMU 2014-06-17 17:09:36 +02:00
reset reset: sunxi: fix spinlock initialization 2015-01-27 08:29:41 -08:00
rpmsg A small pull request consisting of: 2013-05-07 14:02:00 -07:00
rtc drivers/rtc/rtc-s3c.c: add .needs_src_clk to s3c6410 RTC data 2015-03-28 09:59:44 -04:00
s390 KVM: s390: virtio-ccw: don't overwrite config space values 2015-07-20 21:12:42 -04:00
sbus Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc 2014-08-05 18:57:18 -07:00
scsi st: null pointer dereference panic caused by use after kref_put by st_open 2015-08-27 13:25:43 -04:00
sfi SFI / ACPI: Fix warnings reported during builds with W=1 2013-12-07 01:24:33 +01:00
sh drivers: sh: Leave disabling of unused PM domains to genpd 2014-09-09 00:46:13 +02:00
sn Drivers: misc: remove __dev* attributes. 2013-01-03 15:57:16 -08:00
soc soc: versatile: Add terminating entry for realview_soc_of_match 2014-10-28 22:05:07 +01:00
spi spi: orion: Fix maximum baud rates for Armada 370/XP 2015-07-03 23:02:19 -04:00
spmi spmi: Remove duplicate inclusion of module.h 2014-07-10 15:22:13 -07:00
ssb SSB: fix Kconfig dependencies 2015-05-17 19:12:34 -04:00
staging staging: vt6655: device_rx_srv check sk_buff is NULL 2015-07-03 23:02:22 -04:00
target iscsi-target: Convert iscsi_thread_set usage to kthread.h 2015-08-04 14:34:17 -04:00
tc TC: Handle device_register() errors. 2014-06-26 10:48:23 +01:00
thermal thermal: armada: Update Armada 380 thermal sensor coefficients 2015-06-10 13:42:37 -04:00
thunderbolt thunderbolt: Clear hops before overwriting 2014-08-26 14:54:48 -07:00
tty tty/serial: at91: RS485 mode: 0 is valid for delay_rts_after_send 2015-07-12 10:54:24 -04:00
uio uio: Export definition of struct uio_device 2014-10-02 21:35:54 -07:00
usb USB: qcserial: Add support for Dell Wireless 5809e 4G Modem 2015-08-27 13:25:34 -04:00
uwb uwb: add an ASIE sysfs attribute to uwb_rc devices 2014-09-23 22:05:26 -07:00
vfio vfio-pci: Fix the check on pci device type in vfio_pci_probe() 2015-01-27 08:29:40 -08:00
vhost vhost-scsi: Add missing virtio-scsi -> TCM attribute conversion 2015-01-27 08:29:45 -08:00
video video/fbdev: fix defio's fsync 2015-01-27 08:29:39 -08:00
virt drivers: clean-up prom.h implicit includes 2013-10-09 20:04:04 -05:00
virtio virtio-balloon: do not call blocking ops when !TASK_RUNNING 2015-04-16 20:11:27 -04:00
vlynq drivers/vlynq/vlynq.c: fix another resource size off by 1 error 2014-01-23 16:36:55 -08:00
vme vme: bridges: use pci_zalloc_consistent 2014-08-08 15:57:30 -07:00
w1 w1_therm reference count family data 2015-07-03 23:02:19 -04:00
watchdog watchdog: omap: assert the counter being stopped before reprogramming 2015-08-04 14:39:52 -04:00
xen xen/gntdevt: Fix race condition in gntdev_release() 2015-08-27 13:25:25 -04:00
zorro zorro: Use ARRAY_SIZE 2014-07-11 10:38:02 +02:00
Kconfig soc: ti: add Keystone Navigator QMSS driver 2014-09-24 09:49:14 -04:00
Makefile Driver core patches for 3.17-rc1 2014-08-04 18:34:04 -07:00