Commit bb1d1073a10fdc8547e3eb821ee2488260094b39

Authored by brking@us.ibm.com
Committed by James Bottomley
1 parent 15084a4a63

[SCSI] Prevent scsi_execute_async from guessing cdb length

When the scsi_execute_async interface was added it ended up reducing
the flexibility of userspace to send arbitrary scsi commands through
sg using SG_IO. The SG_IO interface allows userspace to specify the
CDB length. This is now ignored in scsi_execute_async and it is
guessed using the COMMAND_SIZE macro, which is not always correct,
particularly for vendor specific commands. This patch adds a cmd_len
parameter to the scsi_execute_async interface to allow the caller
to specify the length of the CDB.

Signed-off-by: Brian King <brking@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

Showing 5 changed files with 7 additions and 6 deletions Side-by-side Diff

drivers/scsi/scsi_error.c
... ... @@ -1350,7 +1350,7 @@
1350 1350 cmnd[4] = SCSI_REMOVAL_PREVENT;
1351 1351 cmnd[5] = 0;
1352 1352  
1353   - scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ,
  1353 + scsi_execute_async(sdev, cmnd, 6, DMA_NONE, NULL, 0, 0, 10 * HZ,
1354 1354 5, NULL, NULL, GFP_KERNEL);
1355 1355 }
1356 1356  
drivers/scsi/scsi_lib.c
... ... @@ -436,6 +436,7 @@
436 436 * scsi_execute_async - insert request
437 437 * @sdev: scsi device
438 438 * @cmd: scsi command
  439 + * @cmd_len: length of scsi cdb
439 440 * @data_direction: data direction
440 441 * @buffer: data buffer (this can be a kernel buffer or scatterlist)
441 442 * @bufflen: len of buffer
... ... @@ -445,7 +446,7 @@
445 446 * @flags: or into request flags
446 447 **/
447 448 int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
448   - int data_direction, void *buffer, unsigned bufflen,
  449 + int cmd_len, int data_direction, void *buffer, unsigned bufflen,
449 450 int use_sg, int timeout, int retries, void *privdata,
450 451 void (*done)(void *, char *, int, int), gfp_t gfp)
451 452 {
... ... @@ -472,7 +473,7 @@
472 473 if (err)
473 474 goto free_req;
474 475  
475   - req->cmd_len = COMMAND_SIZE(cmd[0]);
  476 + req->cmd_len = cmd_len;
476 477 memcpy(req->cmd, cmd, req->cmd_len);
477 478 req->sense = sioc->sense;
478 479 req->sense_len = 0;
... ... @@ -741,7 +741,7 @@
741 741 hp->duration = jiffies_to_msecs(jiffies);
742 742 /* Now send everything of to mid-level. The next time we hear about this
743 743 packet is when sg_cmd_done() is called (i.e. a callback). */
744   - if (scsi_execute_async(sdp->device, cmnd, data_dir, srp->data.buffer,
  744 + if (scsi_execute_async(sdp->device, cmnd, hp->cmd_len, data_dir, srp->data.buffer,
745 745 hp->dxfer_len, srp->data.k_use_sg, timeout,
746 746 SG_DEFAULT_RETRIES, srp, sg_cmd_done,
747 747 GFP_ATOMIC)) {
... ... @@ -508,7 +508,7 @@
508 508 STp->buffer->cmdstat.have_sense = 0;
509 509 STp->buffer->syscall_result = 0;
510 510  
511   - if (scsi_execute_async(STp->device, cmd, direction,
  511 + if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
512 512 &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
513 513 timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
514 514 /* could not allocate the buffer or request was too large */
include/scsi/scsi_device.h
... ... @@ -275,7 +275,7 @@
275 275 int data_direction, void *buffer, unsigned bufflen,
276 276 struct scsi_sense_hdr *, int timeout, int retries);
277 277 extern int scsi_execute_async(struct scsi_device *sdev,
278   - const unsigned char *cmd, int data_direction,
  278 + const unsigned char *cmd, int cmd_len, int data_direction,
279 279 void *buffer, unsigned bufflen, int use_sg,
280 280 int timeout, int retries, void *privdata,
281 281 void (*done)(void *, char *, int, int),