Skip to content

Commit

Permalink
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "Three fixes this time, two in SES picked up by KASAN for various types
  of buffer overrun.  The first is a USB array which returns page 8
  whatever is asked for and causes us to overrun with incorrect data
  format assumptions and the second is an invalid iteration of page 10
  (the additional information page).

  The final fix is a reversion of a NULL deref fix which caused
  suspend/resume not to be called in pairs leading to incorrect device
  operation (Jens has queued a more proper fix for the problem in
  block)"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  ses: fix additional element traversal bug
  Revert "SCSI: Fix NULL pointer dereference in runtime PM"
  ses: Fix problems with simple enclosures
  • Loading branch information
Linus Torvalds committed Dec 19, 2015
2 parents 76b8ebd + ed94724 commit 4fee35a
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
20 changes: 10 additions & 10 deletions drivers/scsi/scsi_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,13 @@ static int sdev_runtime_suspend(struct device *dev)
struct scsi_device *sdev = to_scsi_device(dev);
int err = 0;

if (pm && pm->runtime_suspend) {
err = blk_pre_runtime_suspend(sdev->request_queue);
if (err)
return err;
err = blk_pre_runtime_suspend(sdev->request_queue);
if (err)
return err;
if (pm && pm->runtime_suspend)
err = pm->runtime_suspend(dev);
blk_post_runtime_suspend(sdev->request_queue, err);
}
blk_post_runtime_suspend(sdev->request_queue, err);

return err;
}

Expand All @@ -248,11 +248,11 @@ static int sdev_runtime_resume(struct device *dev)
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int err = 0;

if (pm && pm->runtime_resume) {
blk_pre_runtime_resume(sdev->request_queue);
blk_pre_runtime_resume(sdev->request_queue);
if (pm && pm->runtime_resume)
err = pm->runtime_resume(dev);
blk_post_runtime_resume(sdev->request_queue, err);
}
blk_post_runtime_resume(sdev->request_queue, err);

return err;
}

Expand Down
30 changes: 28 additions & 2 deletions drivers/scsi/ses.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ static void init_device_slot_control(unsigned char *dest_desc,
static int ses_recv_diag(struct scsi_device *sdev, int page_code,
void *buf, int bufflen)
{
int ret;
unsigned char cmd[] = {
RECEIVE_DIAGNOSTIC,
1, /* Set PCV bit */
Expand All @@ -92,9 +93,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code,
bufflen & 0xff,
0
};
unsigned char recv_page_code;

return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
NULL, SES_TIMEOUT, SES_RETRIES, NULL);
if (unlikely(!ret))
return ret;

recv_page_code = ((unsigned char *)buf)[0];

if (likely(recv_page_code == page_code))
return ret;

/* successful diagnostic but wrong page code. This happens to some
* USB devices, just print a message and pretend there was an error */

sdev_printk(KERN_ERR, sdev,
"Wrong diagnostic page; asked for %d got %u\n",
page_code, recv_page_code);

return -EINVAL;
}

static int ses_send_diag(struct scsi_device *sdev, int page_code,
Expand Down Expand Up @@ -541,7 +559,15 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
if (desc_ptr)
desc_ptr += len;

if (addl_desc_ptr)
if (addl_desc_ptr &&
/* only find additional descriptions for specific devices */
(type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE ||
type_ptr[0] == ENCLOSURE_COMPONENT_SAS_EXPANDER ||
/* these elements are optional */
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
addl_desc_ptr += addl_desc_ptr[1] + 2;

}
Expand Down
4 changes: 4 additions & 0 deletions include/linux/enclosure.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
/* A few generic types ... taken from ses-2 */
enum enclosure_component_type {
ENCLOSURE_COMPONENT_DEVICE = 0x01,
ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS = 0x07,
ENCLOSURE_COMPONENT_SCSI_TARGET_PORT = 0x14,
ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT = 0x15,
ENCLOSURE_COMPONENT_ARRAY_DEVICE = 0x17,
ENCLOSURE_COMPONENT_SAS_EXPANDER = 0x18,
};

/* ses-2 common element status */
Expand Down

0 comments on commit 4fee35a

Please sign in to comment.