aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Rosenberg <drosenberg@vsecurity.com>2011-07-11 17:08:23 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-05 00:58:36 -0400
commit43f7c7261fc45a4c09fbd56c0a76dcdf55d8e8f3 (patch)
tree7629f0518818f05916c3af486374a175f39c2312
parent1768e0b7e77b5c3e11cd0f0ab15358ccba3a9880 (diff)
pmcraid: reject negative request size
commit b5b515445f4f5a905c5dd27e6e682868ccd6c09d upstream. There's a code path in pmcraid that can be reached via device ioctl that causes all sorts of ugliness, including heap corruption or triggering the OOM killer due to consecutive allocation of large numbers of pages. First, the user can call pmcraid_chr_ioctl(), with a type PMCRAID_PASSTHROUGH_IOCTL. This calls through to pmcraid_ioctl_passthrough(). Next, a pmcraid_passthrough_ioctl_buffer is copied in, and the request_size variable is set to buffer->ioarcb.data_transfer_length, which is an arbitrary 32-bit signed value provided by the user. If a negative value is provided here, bad things can happen. For example, pmcraid_build_passthrough_ioadls() is called with this request_size, which immediately calls pmcraid_alloc_sglist() with a negative size. The resulting math on allocating a scatter list can result in an overflow in the kzalloc() call (if num_elem is 0, the sglist will be smaller than expected), or if num_elem is unexpectedly large the subsequent loop will call alloc_pages() repeatedly, a high number of pages will be allocated and the OOM killer might be invoked. It looks like preventing this value from being negative in pmcraid_ioctl_passthrough() would be sufficient. Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: James Bottomley <JBottomley@Parallels.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/scsi/pmcraid.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index fca6a895307..d079f9a3c6b 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -3871,6 +3871,9 @@ static long pmcraid_ioctl_passthrough(
3871 pmcraid_err("couldn't build passthrough ioadls\n"); 3871 pmcraid_err("couldn't build passthrough ioadls\n");
3872 goto out_free_buffer; 3872 goto out_free_buffer;
3873 } 3873 }
3874 } else if (request_size < 0) {
3875 rc = -EINVAL;
3876 goto out_free_buffer;
3874 } 3877 }
3875 3878
3876 /* If data is being written into the device, copy the data from user 3879 /* If data is being written into the device, copy the data from user