Commit 09050715 authored by Mark Salyzyn's avatar Mark Salyzyn Committed by James Bottomley

[SCSI] aacraid: prevent copy_from_user() BUG!

Seen:

	kernel BUG at arch/i386/lib/usercopy.c:872

under a 2.6.18-8.el5 kernel. Traced it to a garbage-in/garbage-out
ioctl condition in the aacraid driver.

Adaptec's special ioctl scb passthrough needs to check the validity of
the individual scatter gather count fields to the maximum the adapter
supports. Doing so will have the side effect of preventing
copy_from_user() from bugging out while populating the dma buffers.
This is a hardening effort, issue was triggered by an errant version
of the management tools and thus the BUG should not be seen in the
field.

[jejb: fixed up compile failure]
Signed-off-by: default avatarMark Salyzyn <aacraid@adaptec.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 597136ab
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <scsi/scsi_host.h>
#include "aacraid.h" #include "aacraid.h"
...@@ -581,6 +582,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -581,6 +582,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
for (i = 0; i < upsg->count; i++) { for (i = 0; i < upsg->count; i++) {
u64 addr; u64 addr;
void* p; void* p;
if (upsg->sg[i].count >
(dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
65536) {
rcode = -EINVAL;
goto cleanup;
}
/* Does this really need to be GFP_DMA? */ /* Does this really need to be GFP_DMA? */
p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA);
if(!p) { if(!p) {
...@@ -625,6 +634,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -625,6 +634,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
for (i = 0; i < usg->count; i++) { for (i = 0; i < usg->count; i++) {
u64 addr; u64 addr;
void* p; void* p;
if (usg->sg[i].count >
(dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
65536) {
rcode = -EINVAL;
goto cleanup;
}
/* Does this really need to be GFP_DMA? */ /* Does this really need to be GFP_DMA? */
p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
if(!p) { if(!p) {
...@@ -667,6 +684,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -667,6 +684,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
for (i = 0; i < upsg->count; i++) { for (i = 0; i < upsg->count; i++) {
uintptr_t addr; uintptr_t addr;
void* p; void* p;
if (usg->sg[i].count >
(dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
65536) {
rcode = -EINVAL;
goto cleanup;
}
/* Does this really need to be GFP_DMA? */ /* Does this really need to be GFP_DMA? */
p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
if(!p) { if(!p) {
...@@ -698,6 +723,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -698,6 +723,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
for (i = 0; i < upsg->count; i++) { for (i = 0; i < upsg->count; i++) {
dma_addr_t addr; dma_addr_t addr;
void* p; void* p;
if (upsg->sg[i].count >
(dev->adapter_info.options &
AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) :
65536) {
rcode = -EINVAL;
goto cleanup;
}
p = kmalloc(upsg->sg[i].count, GFP_KERNEL); p = kmalloc(upsg->sg[i].count, GFP_KERNEL);
if (!p) { if (!p) {
dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
......
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