aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2014-10-24 08:26:57 -0400
committerChristoph Hellwig <hch@lst.de>2014-11-12 05:16:03 -0500
commita9a47bf58ac1d5525ae99922e055d8de87eeae78 (patch)
treeb6f3e5f7ed4879e19fb898774dcd2db8e6e3c43c
parent2478a736a7d01e3ef8d273e8fc5b11b6ed9af3ea (diff)
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: Hannes Reinecke <hare@suse.de> Reviewed-by: Robert Elliott <elliott@hp.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/arm/fas216.c2
-rw-r--r--drivers/scsi/ch.c24
-rw-r--r--drivers/scsi/constants.c25
-rw-r--r--drivers/scsi/sr_ioctl.c4
-rw-r--r--include/scsi/scsi_dbg.h2
5 files changed, 27 insertions, 30 deletions
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index cea34633b90a..d2581cb41ec8 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2424,7 +2424,7 @@ int fas216_eh_abort(struct scsi_cmnd *SCpnt)
2424 info->stats.aborts += 1; 2424 info->stats.aborts += 1;
2425 2425
2426 printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no); 2426 printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no);
2427 __scsi_print_command(SCpnt->cmnd); 2427 __scsi_print_command(SCpnt->cmnd, SCpnt->cmd_len);
2428 2428
2429 print_debug_list(); 2429 print_debug_list();
2430 fas216_dumpstate(info); 2430 fas216_dumpstate(info);
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 53621a34c5f9..226ef771efff 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -182,7 +182,7 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr)
182} 182}
183 183
184static int 184static int
185ch_do_scsi(scsi_changer *ch, unsigned char *cmd, 185ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
186 void *buffer, unsigned buflength, 186 void *buffer, unsigned buflength,
187 enum dma_data_direction direction) 187 enum dma_data_direction direction)
188{ 188{
@@ -196,7 +196,7 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd,
196 errno = 0; 196 errno = 0;
197 if (debug) { 197 if (debug) {
198 DPRINTK("command: "); 198 DPRINTK("command: ");
199 __scsi_print_command(cmd); 199 __scsi_print_command(cmd, cmd_len);
200 } 200 }
201 201
202 result = scsi_execute_req(ch->device, cmd, direction, buffer, 202 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 cmd[3] = elem & 0xff; 257 cmd[3] = elem & 0xff;
258 cmd[5] = 1; 258 cmd[5] = 1;
259 cmd[9] = 255; 259 cmd[9] = 255;
260 if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) { 260 if (0 == (result = ch_do_scsi(ch, cmd, 12,
261 buffer, 256, DMA_FROM_DEVICE))) {
261 if (((buffer[16] << 8) | buffer[17]) != elem) { 262 if (((buffer[16] << 8) | buffer[17]) != elem) {
262 DPRINTK("asked for element 0x%02x, got 0x%02x\n", 263 DPRINTK("asked for element 0x%02x, got 0x%02x\n",
263 elem,(buffer[16] << 8) | buffer[17]); 264 elem,(buffer[16] << 8) | buffer[17]);
@@ -287,7 +288,7 @@ ch_init_elem(scsi_changer *ch)
287 memset(cmd,0,sizeof(cmd)); 288 memset(cmd,0,sizeof(cmd));
288 cmd[0] = INITIALIZE_ELEMENT_STATUS; 289 cmd[0] = INITIALIZE_ELEMENT_STATUS;
289 cmd[1] = (ch->device->lun & 0x7) << 5; 290 cmd[1] = (ch->device->lun & 0x7) << 5;
290 err = ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE); 291 err = ch_do_scsi(ch, cmd, 6, NULL, 0, DMA_NONE);
291 VPRINTK(KERN_INFO, "... finished\n"); 292 VPRINTK(KERN_INFO, "... finished\n");
292 return err; 293 return err;
293} 294}
@@ -309,10 +310,10 @@ ch_readconfig(scsi_changer *ch)
309 cmd[1] = (ch->device->lun & 0x7) << 5; 310 cmd[1] = (ch->device->lun & 0x7) << 5;
310 cmd[2] = 0x1d; 311 cmd[2] = 0x1d;
311 cmd[4] = 255; 312 cmd[4] = 255;
312 result = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE); 313 result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
313 if (0 != result) { 314 if (0 != result) {
314 cmd[1] |= (1<<3); 315 cmd[1] |= (1<<3);
315 result = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE); 316 result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
316 } 317 }
317 if (0 == result) { 318 if (0 == result) {
318 ch->firsts[CHET_MT] = 319 ch->firsts[CHET_MT] =
@@ -437,7 +438,7 @@ ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate)
437 cmd[4] = (elem >> 8) & 0xff; 438 cmd[4] = (elem >> 8) & 0xff;
438 cmd[5] = elem & 0xff; 439 cmd[5] = elem & 0xff;
439 cmd[8] = rotate ? 1 : 0; 440 cmd[8] = rotate ? 1 : 0;
440 return ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE); 441 return ch_do_scsi(ch, cmd, 10, NULL, 0, DMA_NONE);
441} 442}
442 443
443static int 444static int
@@ -458,7 +459,7 @@ ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate)
458 cmd[6] = (dest >> 8) & 0xff; 459 cmd[6] = (dest >> 8) & 0xff;
459 cmd[7] = dest & 0xff; 460 cmd[7] = dest & 0xff;
460 cmd[10] = rotate ? 1 : 0; 461 cmd[10] = rotate ? 1 : 0;
461 return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE); 462 return ch_do_scsi(ch, cmd, 12, NULL,0, DMA_NONE);
462} 463}
463 464
464static int 465static int
@@ -484,7 +485,7 @@ ch_exchange(scsi_changer *ch, u_int trans, u_int src,
484 cmd[9] = dest2 & 0xff; 485 cmd[9] = dest2 & 0xff;
485 cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0); 486 cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0);
486 487
487 return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE); 488 return ch_do_scsi(ch, cmd, 12, NULL, 0, DMA_NONE);
488} 489}
489 490
490static void 491static void
@@ -534,7 +535,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem,
534 memcpy(buffer,tag,32); 535 memcpy(buffer,tag,32);
535 ch_check_voltag(buffer); 536 ch_check_voltag(buffer);
536 537
537 result = ch_do_scsi(ch, cmd, buffer, 256, DMA_TO_DEVICE); 538 result = ch_do_scsi(ch, cmd, 12, buffer, 256, DMA_TO_DEVICE);
538 kfree(buffer); 539 kfree(buffer);
539 return result; 540 return result;
540} 541}
@@ -765,7 +766,8 @@ static long ch_ioctl(struct file *file,
765 ch_cmd[5] = 1; 766 ch_cmd[5] = 1;
766 ch_cmd[9] = 255; 767 ch_cmd[9] = 255;
767 768
768 result = ch_do_scsi(ch, ch_cmd, buffer, 256, DMA_FROM_DEVICE); 769 result = ch_do_scsi(ch, ch_cmd, 12,
770 buffer, 256, DMA_FROM_DEVICE);
769 if (!result) { 771 if (!result) {
770 cge.cge_status = buffer[18]; 772 cge.cge_status = buffer[18];
771 cge.cge_flags = 0; 773 cge.cge_flags = 0;
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index dc1b18c821ed..a84ced0de02b 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -320,25 +320,21 @@ static bool scsi_opcode_sa_name(int opcode, int service_action,
320 return true; 320 return true;
321} 321}
322 322
323/* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ 323static void print_opcode_name(const unsigned char *cdbp, size_t cdb_len)
324static void print_opcode_name(unsigned char * cdbp, int cdb_len)
325{ 324{
326 int sa, len, cdb0; 325 int sa, cdb0;
327 const char *cdb_name = NULL, *sa_name = NULL; 326 const char *cdb_name = NULL, *sa_name = NULL;
328 327
329 cdb0 = cdbp[0]; 328 cdb0 = cdbp[0];
330 if (cdb0 == VARIABLE_LENGTH_CMD) { 329 if (cdb0 == VARIABLE_LENGTH_CMD) {
331 len = scsi_varlen_cdb_length(cdbp); 330 if (cdb_len < 10) {
332 if (len < 10) { 331 printk("short variable length command, len=%zu",
333 printk("short variable length command, " 332 cdb_len);
334 "len=%d ext_len=%d", len, cdb_len);
335 return; 333 return;
336 } 334 }
337 sa = (cdbp[8] << 8) + cdbp[9]; 335 sa = (cdbp[8] << 8) + cdbp[9];
338 } else { 336 } else
339 sa = cdbp[1] & 0x1f; 337 sa = cdbp[1] & 0x1f;
340 len = cdb_len;
341 }
342 338
343 if (!scsi_opcode_sa_name(cdb0, sa, &cdb_name, &sa_name)) { 339 if (!scsi_opcode_sa_name(cdb0, sa, &cdb_name, &sa_name)) {
344 if (cdb_name) 340 if (cdb_name)
@@ -356,18 +352,17 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
356 printk("%s, sa=0x%x", cdb_name, sa); 352 printk("%s, sa=0x%x", cdb_name, sa);
357 else 353 else
358 printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); 354 printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
359
360 if (cdb_len > 0 && len != cdb_len)
361 printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
362 } 355 }
363} 356}
364 357
365void __scsi_print_command(unsigned char *cdb) 358void __scsi_print_command(const unsigned char *cdb, size_t cdb_len)
366{ 359{
367 int k, len; 360 int k, len;
368 361
369 print_opcode_name(cdb, 0); 362 print_opcode_name(cdb, cdb_len);
370 len = scsi_command_size(cdb); 363 len = scsi_command_size(cdb);
364 if (cdb_len < len)
365 len = cdb_len;
371 /* print out all bytes in cdb */ 366 /* print out all bytes in cdb */
372 for (k = 0; k < len; ++k) 367 for (k = 0; k < len; ++k)
373 printk(" %02x", cdb[k]); 368 printk(" %02x", cdb[k]);
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 17e0c2b28a99..fb929fac22ba 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -257,14 +257,14 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
257 /* sense: Invalid command operation code */ 257 /* sense: Invalid command operation code */
258 err = -EDRIVE_CANT_DO_THIS; 258 err = -EDRIVE_CANT_DO_THIS;
259#ifdef DEBUG 259#ifdef DEBUG
260 __scsi_print_command(cgc->cmd); 260 __scsi_print_command(cgc->cmd, CDROM_PACKET_SIZE);
261 scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr); 261 scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr);
262#endif 262#endif
263 break; 263 break;
264 default: 264 default:
265 sr_printk(KERN_ERR, cd, 265 sr_printk(KERN_ERR, cd,
266 "CDROM (ioctl) error, command: "); 266 "CDROM (ioctl) error, command: ");
267 __scsi_print_command(cgc->cmd); 267 __scsi_print_command(cgc->cmd, CDROM_PACKET_SIZE);
268 scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr); 268 scsi_print_sense_hdr(cd->device, cd->cdi.name, &sshdr);
269 err = -EIO; 269 err = -EIO;
270 } 270 }
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index 386474ee53a1..81d041822229 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -6,7 +6,7 @@ struct scsi_device;
6struct scsi_sense_hdr; 6struct scsi_sense_hdr;
7 7
8extern void scsi_print_command(struct scsi_cmnd *); 8extern void scsi_print_command(struct scsi_cmnd *);
9extern void __scsi_print_command(unsigned char *); 9extern void __scsi_print_command(const unsigned char *, size_t);
10extern void scsi_show_extd_sense(const struct scsi_device *, const char *, 10extern void scsi_show_extd_sense(const struct scsi_device *, const char *,
11 unsigned char, unsigned char); 11 unsigned char, unsigned char);
12extern void scsi_show_sense_hdr(const struct scsi_device *, const char *, 12extern void scsi_show_sense_hdr(const struct scsi_device *, const char *,