diff options
Diffstat (limited to 'drivers')
| -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 */ |
