Commit a9a47bf5 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Christoph Hellwig

scsi: repurpose the last argument from print_opcode_name()

print_opcode_name() was only ever called with a '0' argument
from LLDDs and ULDs which were _not_ supporting variable length
CDBs, so the 'if' clause was never triggered.
Instead we should be using the last argument to specify
the cdb length to avoid accidental overflow when reading
the cdb buffer.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarRobert Elliott <elliott@hp.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 2478a736
...@@ -2424,7 +2424,7 @@ int fas216_eh_abort(struct scsi_cmnd *SCpnt) ...@@ -2424,7 +2424,7 @@ int fas216_eh_abort(struct scsi_cmnd *SCpnt)
info->stats.aborts += 1; info->stats.aborts += 1;
printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no); printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no);
__scsi_print_command(SCpnt->cmnd); __scsi_print_command(SCpnt->cmnd, SCpnt->cmd_len);
print_debug_list(); print_debug_list();
fas216_dumpstate(info); fas216_dumpstate(info);
......
...@@ -182,7 +182,7 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr) ...@@ -182,7 +182,7 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr)
} }
static int static int
ch_do_scsi(scsi_changer *ch, unsigned char *cmd, ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
void *buffer, unsigned buflength, void *buffer, unsigned buflength,
enum dma_data_direction direction) enum dma_data_direction direction)
{ {
...@@ -196,7 +196,7 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, ...@@ -196,7 +196,7 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd,
errno = 0; errno = 0;
if (debug) { if (debug) {
DPRINTK("command: "); DPRINTK("command: ");
__scsi_print_command(cmd); __scsi_print_command(cmd, cmd_len);
} }
result = scsi_execute_req(ch->device, cmd, direction, buffer, result = scsi_execute_req(ch->device, cmd, direction, buffer,
...@@ -257,7 +257,8 @@ ch_read_element_status(scsi_changer *ch, u_int elem, char *data) ...@@ -257,7 +257,8 @@ ch_read_element_status(scsi_changer *ch, u_int elem, char *data)
cmd[3] = elem & 0xff; cmd[3] = elem & 0xff;
cmd[5] = 1; cmd[5] = 1;
cmd[9] = 255; cmd[9] = 255;
if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) { if (0 == (result = ch_do_scsi(ch, cmd, 12,
buffer, 256, DMA_FROM_DEVICE))) {
if (((buffer[16] << 8) | buffer[17]) != elem) { if (((buffer[16] << 8) | buffer[17]) != elem) {
DPRINTK("asked for element 0x%02x, got 0x%02x\n", DPRINTK("asked for element 0x%02x, got 0x%02x\n",
elem,(buffer[16] << 8) | buffer[17]); elem,(buffer[16] << 8) | buffer[17]);
...@@ -287,7 +288,7 @@ ch_init_elem(scsi_changer *ch) ...@@ -287,7 +288,7 @@ ch_init_elem(scsi_changer *ch)
memset(cmd,0,sizeof(cmd)); memset(cmd,0,sizeof(cmd));
cmd[0] = INITIALIZE_ELEMENT_STATUS; cmd[0] = INITIALIZE_ELEMENT_STATUS;
cmd[1] = (ch->device->lun & 0x7) << 5; cmd[1] = (ch->device->lun & 0x7) << 5;
err = ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE); err = ch_do_scsi(ch, cmd, 6, NULL, 0, DMA_NONE);
VPRINTK(KERN_INFO, "... finished\n"); VPRINTK(KERN_INFO, "... finished\n");
return err; return err;
} }
...@@ -309,10 +310,10 @@ ch_readconfig(scsi_changer *ch) ...@@ -309,10 +310,10 @@ ch_readconfig(scsi_changer *ch)
cmd[1] = (ch->device->lun & 0x7) << 5; cmd[1] = (ch->device->lun & 0x7) << 5;
cmd[2] = 0x1d; cmd[2] = 0x1d;
cmd[4] = 255; cmd[4] = 255;
result = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE); result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
if (0 != result) { if (0 != result) {
cmd[1] |= (1<<3); cmd[1] |= (1<<3);
result = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE); result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
} }
if (0 == result) { if (0 == result) {
ch->firsts[CHET_MT] = ch->firsts[CHET_MT] =
...@@ -437,7 +438,7 @@ ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate) ...@@ -437,7 +438,7 @@ ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate)
cmd[4] = (elem >> 8) & 0xff; cmd[4] = (elem >> 8) & 0xff;
cmd[5] = elem & 0xff; cmd[5] = elem & 0xff;
cmd[8] = rotate ? 1 : 0; cmd[8] = rotate ? 1 : 0;
return ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE); return ch_do_scsi(ch, cmd, 10, NULL, 0, DMA_NONE);
} }
static int static int
...@@ -458,7 +459,7 @@ ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate) ...@@ -458,7 +459,7 @@ ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate)
cmd[6] = (dest >> 8) & 0xff; cmd[6] = (dest >> 8) & 0xff;
cmd[7] = dest & 0xff; cmd[7] = dest & 0xff;
cmd[10] = rotate ? 1 : 0; cmd[10] = rotate ? 1 : 0;
return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE); return ch_do_scsi(ch, cmd, 12, NULL,0, DMA_NONE);
} }
static int static int
...@@ -484,7 +485,7 @@ ch_exchange(scsi_changer *ch, u_int trans, u_int src, ...@@ -484,7 +485,7 @@ ch_exchange(scsi_changer *ch, u_int trans, u_int src,
cmd[9] = dest2 & 0xff; cmd[9] = dest2 & 0xff;
cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0); cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0);
return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE); return ch_do_scsi(ch, cmd, 12, NULL, 0, DMA_NONE);
} }
static void static void
...@@ -534,7 +535,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem, ...@@ -534,7 +535,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem,
memcpy(buffer,tag,32); memcpy(buffer,tag,32);
ch_check_voltag(buffer); ch_check_voltag(buffer);
result = ch_do_scsi(ch, cmd, buffer, 256, DMA_TO_DEVICE); result = ch_do_scsi(ch, cmd, 12, buffer, 256, DMA_TO_DEVICE);
kfree(buffer); kfree(buffer);
return result; return result;
} }
...@@ -765,7 +766,8 @@ static long ch_ioctl(struct file *file, ...@@ -765,7 +766,8 @@ static long ch_ioctl(struct file *file,
ch_cmd[5] = 1; ch_cmd[5] = 1;
ch_cmd[9] = 255; ch_cmd[9] = 255;
result = ch_do_scsi(ch, ch_cmd, buffer, 256, DMA_FROM_DEVICE); result = ch_do_scsi(ch, ch_cmd, 12,
buffer, 256, DMA_FROM_DEVICE);
if (!result) { if (!result) {
cge.cge_status = buffer[18]; cge.cge_status = buffer[18];
cge.cge_flags = 0; cge.cge_flags = 0;
......
...@@ -320,25 +320,21 @@ static bool scsi_opcode_sa_name(int opcode, int service_action, ...@@ -320,25 +320,21 @@ static bool scsi_opcode_sa_name(int opcode, int service_action,
return true; return true;
} }
/* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ static void print_opcode_name(const unsigned char *cdbp, size_t cdb_len)
static void print_opcode_name(unsigned char * cdbp, int cdb_len)
{ {
int sa, len, cdb0; int sa, cdb0;
const char *cdb_name = NULL, *sa_name = NULL; const char *cdb_name = NULL, *sa_name = NULL;
cdb0 = cdbp[0]; cdb0 = cdbp[0];
if (cdb0 == VARIABLE_LENGTH_CMD) { if (cdb0 == VARIABLE_LENGTH_CMD) {
len = scsi_varlen_cdb_length(cdbp); if (cdb_len < 10) {
if (len < 10) { printk("short variable length command, len=%zu",
printk("short variable length command, " cdb_len);
"len=%d ext_len=%d", len, cdb_len);
return; return;
} }
sa = (cdbp[8] << 8) + cdbp[9]; sa = (cdbp[8] << 8) + cdbp[9];
} else { } else
sa = cdbp[1] & 0x1f; sa = cdbp[1] & 0x1f;
len = cdb_len;
}
if (!scsi_opcode_sa_name(cdb0, sa, &cdb_name, &sa_name)) { if (!scsi_opcode_sa_name(cdb0, sa, &cdb_name, &sa_name)) {
if (cdb_name) if (cdb_name)
...@@ -356,18 +352,17 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) ...@@ -356,18 +352,17 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
printk("%s, sa=0x%x", cdb_name, sa); printk("%s, sa=0x%x", cdb_name, sa);
else else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
if (cdb_len > 0 && len != cdb_len)
printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
} }
} }
void __scsi_print_command(unsigned char *cdb) void __scsi_print_command(const unsigned char *cdb, size_t cdb_len)
{ {
int k, len; int k, len;
print_opcode_name(cdb, 0); print_opcode_name(cdb, cdb_len);
len = scsi_command_size(cdb); len = scsi_command_size(cdb);
if (cdb_len < len)
len = cdb_len;
/* print out all bytes in cdb */ /* print out all bytes in cdb */
for (k = 0; k < len; ++k) for (k = 0; k < len; ++k)
printk(" %02x", cdb[k]); printk(" %02x", cdb[k]);
......
...@@ -257,14 +257,14 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) ...@@ -257,14 +257,14 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
/* sense: Invalid command operation code */ /* sense: Invalid command operation code */
err = -EDRIVE_CANT_DO_THIS; err = -EDRIVE_CANT_DO_THIS;
#ifdef DEBUG #ifdef DEBUG
__scsi_print_command(cgc->cmd); __scsi_print_command(cgc->cmd, CDROM_PACKET_SIZE);
scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr); scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr);
#endif #endif
break; break;
default: default:
sr_printk(KERN_ERR, cd, sr_printk(KERN_ERR, cd,
"CDROM (ioctl) error, command: "); "CDROM (ioctl) error, command: ");
__scsi_print_command(cgc->cmd); __scsi_print_command(cgc->cmd, CDROM_PACKET_SIZE);
scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr); scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr);
err = -EIO; err = -EIO;
} }
......
...@@ -6,7 +6,7 @@ struct scsi_device; ...@@ -6,7 +6,7 @@ struct scsi_device;
struct scsi_sense_hdr; struct scsi_sense_hdr;
extern void scsi_print_command(struct scsi_cmnd *); extern void scsi_print_command(struct scsi_cmnd *);
extern void __scsi_print_command(unsigned char *); extern void __scsi_print_command(const unsigned char *, size_t);
extern void scsi_show_extd_sense(const struct scsi_device *, const char *, extern void scsi_show_extd_sense(const struct scsi_device *, const char *,
unsigned char, unsigned char); unsigned char, unsigned char);
extern void scsi_show_sense_hdr(const struct scsi_device *, const char *, extern void scsi_show_sense_hdr(const struct scsi_device *, const char *,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment