From d6216c4734721900a835196309668134f83c641d Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 11 Feb 2014 22:22:47 +0100 Subject: [PATCH] [SCSI] st: fix corruption of the st_modedef structures in st_set_options() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When copying the st_modedef structures the devs pointers must be preserved in the same way as with the cdevs pointers. This fixes bug 70271: https://bugzilla.kernel.org/show_bug.cgi?id=70271 [ 135.037052] BUG: unable to handle kernel NULL pointer dereference at 0000000000000098 [ 135.045048] IP: [] kernfs_find_ns+0x21/0x150 [ 135.050999] PGD 220623067 PUD 222171067 PMD 0 [ 135.055593] Oops: 0000 [#1] SMP [ 135.058938] Modules linked in: bnx2fc cnic uio fcoe libfcoe libfc 8021q mrp scsi_transport_fc garp scsi_tgt stp llc binfmt_misc dm_round_robin dm_multipath uinput iTCO_wdt iTCO_vendor_support microcode sg pcspkr serio_raw osst st(-) i2c_i801 lpc_ich mfd_core e1000e ptp pps_core ipmi_si ipmi_msghandler video tpm_infineon ext4(F) jbd2(F) mbcache(F) sd_mod(F) crc_t10dif(F) crct10dif_common(F) sr_mod(F) cdrom(F) pata_acpi(F) ata_generic(F) ata_piix(F) libata(F) mpt2sas(F) scsi_transport_sas(F) raid_class(F) ast(F) ttm(F) drm_kms_helper(F) drm(F) i2c_algo_bit(F) sysimgblt(F) sysfillrect(F) i2c_core(F) syscopyarea(F) dm_mirror(F) dm_region_hash(F) dm_log(F) dm_mod(F) [ 135.119686] CPU: 2 PID: 2028 Comm: rmmod Tainted: GF 3.14.0-rc1-linux-mainline+ #14 [ 135.128453] Hardware name: wortmann To be filled by O.E.M./P8B-M Series, BIOS 6103 12/06/2012 [ 135.137127] task: ffff880001de29d0 ti: ffff8802206e4000 task.ti: ffff8802206e4000 [ 135.144742] RIP: 0010:[] [] kernfs_find_ns+0x21/0x150 [ 135.153148] RSP: 0018:ffff8802206e5c98 EFLAGS: 00010282 [ 135.158562] RAX: ffff880001de29d0 RBX: 0000000000000000 RCX: 0000000000000006 [ 135.165814] RDX: 0000000000000000 RSI: ffffffff817627e0 RDI: 0000000000000000 [ 135.173040] RBP: ffff8802206e5cc8 R08: 0000000000000000 R09: 0000000000000001 [ 135.180303] R10: 0000000000000000 R11: 0000000000000001 R12: ffffffff817627e0 [ 135.187554] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000001 [ 135.194774] FS: 00007f817c720700(0000) GS:ffff880227200000(0000) knlGS:0000000000000000 [ 135.202995] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 135.208878] CR2: 0000000000000098 CR3: 00000002219b0000 CR4: 00000000000407e0 [ 135.216139] Stack: [ 135.218185] ffffffff81af63a0 0000000000000000 ffffffff817627e0 0000000000000000 [ 135.225783] 0000000000000000 0000000000000001 ffff8802206e5cf8 ffffffff812af8de [ 135.233347] ffff880226801900 ffffffff81b43320 0000000000000000 ffff880221a7c1c0 [ 135.240972] Call Trace: [ 135.243463] [] kernfs_find_and_get_ns+0x3e/0x70 [ 135.249743] [] sysfs_unmerge_group+0x1d/0x60 [ 135.255716] [] pm_qos_sysfs_remove_latency+0x19/0x20 [ 135.262430] [] dev_pm_qos_constraints_destroy+0x31/0x1e0 [ 135.269500] [] dpm_sysfs_remove+0x16/0x50 [ 135.275263] [] device_del+0x47/0x1e0 [ 135.280554] [] device_unregister+0x22/0x60 [ 135.286406] [] remove_cdevs+0x4d/0x90 [st] [ 135.292247] [] st_remove+0x3f/0xb0 [st] [ 135.297851] [] __device_release_driver+0x7f/0xf0 [ 135.304237] [] driver_detach+0xd8/0xe0 [ 135.309722] [] bus_remove_driver+0x5c/0xd0 [ 135.315553] [] driver_unregister+0x30/0x70 [ 135.321366] [] exit_st+0x5c/0x868 [st] [ 135.326861] [] SyS_delete_module+0x19a/0x1f0 [ 135.332891] [] ? trace_hardirqs_on+0xd/0x10 [ 135.338811] [] ? __audit_syscall_entry+0x94/0x100 [ 135.345282] [] ? trace_hardirqs_on_thunk+0x3a/0x3f [ 135.351806] [] system_call_fastpath+0x16/0x1b [ 135.357859] Code: ff eb e3 0f 1f 80 00 00 00 00 55 48 89 e5 48 83 ec 30 48 89 5d d8 4c 89 65 e0 4c 89 6d e8 4c 89 75 f0 4c 89 7d f8 66 66 66 66 90 <44> 0f b7 bf 98 00 00 00 8b 05 71 6d 87 00 48 89 fb 49 89 f4 49 [ 135.378282] RIP [] kernfs_find_ns+0x21/0x150 [ 135.384355] RSP [ 135.387881] CR2: 0000000000000098 [ 135.391298] ---[ end trace 1968409221ddb3c8 ]--- Signed-off-by: Maurizio Lombardi Acked-by: Kai Mäkisara Signed-off-by: James Bottomley --- drivers/scsi/st.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index a1d6986261a3..afc834e172c6 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -2198,12 +2198,19 @@ static int st_set_options(struct scsi_tape *STp, long options) struct st_modedef *STm; char *name = tape_name(STp); struct cdev *cd0, *cd1; + struct device *d0, *d1; STm = &(STp->modes[STp->current_mode]); if (!STm->defined) { - cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1]; + cd0 = STm->cdevs[0]; + cd1 = STm->cdevs[1]; + d0 = STm->devs[0]; + d1 = STm->devs[1]; memcpy(STm, &(STp->modes[0]), sizeof(struct st_modedef)); - STm->cdevs[0] = cd0; STm->cdevs[1] = cd1; + STm->cdevs[0] = cd0; + STm->cdevs[1] = cd1; + STm->devs[0] = d0; + STm->devs[1] = d1; modes_defined = 1; DEBC(printk(ST_DEB_MSG "%s: Initialized mode %d definition from mode 0\n", -- 2.39.5