Commit fa66b909 authored by Markus Armbruster's avatar Markus Armbruster Committed by Kevin Wolf
Browse files

scsi: scsi_bus_legacy_handle_cmdline() can fail, fix callers



None of its callers checks for failure.  scsi_hot_add() can crash
because of that:

(qemu) drive_add 4 if=scsi,format=host_device,file=/dev/sg1
scsi-generic: scsi generic interface too old
Segmentation fault (core dumped)

Fix all callers, not just scsi_hot_add().

Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 39508e7a
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -679,8 +679,7 @@ static int esp_init1(SysBusDevice *dev)
    qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);

    scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
    scsi_bus_legacy_handle_cmdline(&s->bus);
    return 0;
    return scsi_bus_legacy_handle_cmdline(&s->bus);
}

static SysBusDeviceInfo esp_info = {
+1 −1
Original line number Diff line number Diff line
@@ -2176,7 +2176,7 @@ static int lsi_scsi_init(PCIDevice *dev)

    scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete);
    if (!dev->qdev.hotplugged) {
        scsi_bus_legacy_handle_cmdline(&s->bus);
        return scsi_bus_legacy_handle_cmdline(&s->bus);
    }
    return 0;
}
+3 −0
Original line number Diff line number Diff line
@@ -90,6 +90,9 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
     */
    dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
    scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit);
    if (!scsidev) {
        return -1;
    }
    dinfo->unit = scsidev->id;

    if (printinfo)
+7 −4
Original line number Diff line number Diff line
@@ -83,7 +83,6 @@ void scsi_qdev_register(SCSIDeviceInfo *info)
}

/* handle legacy '-drive if=scsi,...' cmd line args */
/* FIXME callers should check for failure, but don't */
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit)
{
    const char *driver;
@@ -98,18 +97,22 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit)
    return DO_UPCAST(SCSIDevice, qdev, dev);
}

void scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
{
    DriveInfo *dinfo;
    int unit;
    int res = 0, unit;

    for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
        dinfo = drive_get(IF_SCSI, bus->busnr, unit);
        if (dinfo == NULL) {
            continue;
        }
        scsi_bus_legacy_add_drive(bus, dinfo, unit);
        if (!scsi_bus_legacy_add_drive(bus, dinfo, unit)) {
            res = -1;
            break;
        }
    }
    return res;
}

void scsi_dev_clear_sense(SCSIDevice *dev)
+1 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
}

SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit);
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);

void scsi_dev_clear_sense(SCSIDevice *dev);
void scsi_dev_set_sense(SCSIDevice *dev, uint8_t key);
Loading