diff options
Diffstat (limited to 'drivers/usb/class/usbtmc.c')
-rw-r--r-- | drivers/usb/class/usbtmc.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 4f0858fbf980..5bab8e596c88 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -369,13 +369,13 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
369 | { | 369 | { |
370 | struct usbtmc_device_data *data; | 370 | struct usbtmc_device_data *data; |
371 | struct device *dev; | 371 | struct device *dev; |
372 | unsigned long int n_characters; | 372 | u32 n_characters; |
373 | u8 *buffer; | 373 | u8 *buffer; |
374 | int actual; | 374 | int actual; |
375 | int done; | 375 | size_t done; |
376 | int remaining; | 376 | size_t remaining; |
377 | int retval; | 377 | int retval; |
378 | int this_part; | 378 | size_t this_part; |
379 | 379 | ||
380 | /* Get pointer to private data structure */ | 380 | /* Get pointer to private data structure */ |
381 | data = filp->private_data; | 381 | data = filp->private_data; |
@@ -461,6 +461,18 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
461 | (buffer[6] << 16) + | 461 | (buffer[6] << 16) + |
462 | (buffer[7] << 24); | 462 | (buffer[7] << 24); |
463 | 463 | ||
464 | /* Ensure the instrument doesn't lie about it */ | ||
465 | if(n_characters > actual - 12) { | ||
466 | dev_err(dev, "Device lies about message size: %zu > %zu\n", n_characters, actual - 12); | ||
467 | n_characters = actual - 12; | ||
468 | } | ||
469 | |||
470 | /* Ensure the instrument doesn't send more back than requested */ | ||
471 | if(n_characters > this_part) { | ||
472 | dev_err(dev, "Device returns more than requested: %zu > %zu\n", done + n_characters, done + this_part); | ||
473 | n_characters = this_part; | ||
474 | } | ||
475 | |||
464 | /* Copy buffer to user space */ | 476 | /* Copy buffer to user space */ |
465 | if (copy_to_user(buf + done, &buffer[12], n_characters)) { | 477 | if (copy_to_user(buf + done, &buffer[12], n_characters)) { |
466 | /* There must have been an addressing problem */ | 478 | /* There must have been an addressing problem */ |
@@ -471,6 +483,8 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
471 | done += n_characters; | 483 | done += n_characters; |
472 | if (n_characters < USBTMC_SIZE_IOBUFFER) | 484 | if (n_characters < USBTMC_SIZE_IOBUFFER) |
473 | remaining = 0; | 485 | remaining = 0; |
486 | else | ||
487 | remaining -= n_characters; | ||
474 | } | 488 | } |
475 | 489 | ||
476 | /* Update file position value */ | 490 | /* Update file position value */ |