• Meelis Roos's avatar
    scsi: aacraid: fix shutdown crash when init fails · 00c20cdc
    Meelis Roos authored
    When aacraid init fails with "AAC0: adapter self-test failed.", shutdown
    leads to UBSAN warning and then oops:
    
    [154316.118423] ================================================================================
    [154316.118508] UBSAN: Undefined behaviour in drivers/scsi/scsi_lib.c:2328:27
    [154316.118566] member access within null pointer of type 'struct Scsi_Host'
    [154316.118631] CPU: 2 PID: 14530 Comm: reboot Tainted: G        W        4.15.0-dirty #89
    [154316.118701] Hardware name: Hewlett Packard HP NetServer/HP System Board, BIOS 4.06.46 PW 06/25/2003
    [154316.118774] Call Trace:
    [154316.118848]  dump_stack+0x48/0x65
    [154316.118916]  ubsan_epilogue+0xe/0x40
    [154316.118976]  __ubsan_handle_type_mismatch+0xfb/0x180
    [154316.119043]  scsi_block_requests+0x20/0x30
    [154316.119135]  aac_shutdown+0x18/0x40 [aacraid]
    [154316.119196]  pci_device_shutdown+0x33/0x50
    [154316.119269]  device_shutdown+0x18a/0x390
    [...]
    [154316.123435] BUG: unable to handle kernel NULL pointer dereference at 000000f4
    [154316.123515] IP: scsi_block_requests+0xa/0x30
    
    This is because aac_shutdown() does
    
            struct Scsi_Host *shost = pci_get_drvdata(dev);
            scsi_block_requests(shost);
    
    and that assumes shost has been assigned with pci_set_drvdata().
    
    However, pci_set_drvdata(pdev, shost) is done in aac_probe_one() far
    after bailing out with error from calling the init function
    ((*aac_drivers[index].init)(aac)), and when the init function fails, no
    error is returned from aac_probe_one() so PCI layer assumes there is
    driver attached, and tries to shut it down later.
    
    Fix it by returning error from aac_probe_one() when card-specific init
    function fails.
    
    This fixes reboot on my HP NetRAID-4M with dead battery.
    Signed-off-by: default avatarMeelis Roos <mroos@linux.ee>
    Reviewed-by: default avatarDave Carroll <david.carroll@microsemi.com>
    Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    00c20cdc
linit.c 62 KB