aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/commctrl.c
diff options
context:
space:
mode:
authorMark Salyzyn <Mark_Salyzyn@adaptec.com>2008-05-28 15:32:55 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-12 09:22:24 -0400
commit090507157f3bc43dd925fda50f8aca7d03b616b6 (patch)
tree9663be82ffcdfb6036c9138a94bc966e63d077af /drivers/scsi/aacraid/commctrl.c
parent597136ab70a6dccba5c40ee6eed88e881412429b (diff)
[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: Mark Salyzyn <aacraid@adaptec.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/aacraid/commctrl.c')
-rw-r--r--drivers/scsi/aacraid/commctrl.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 5fd83deab36c..a7355260cfcf 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -41,6 +41,7 @@
41#include <linux/kthread.h> 41#include <linux/kthread.h>
42#include <linux/semaphore.h> 42#include <linux/semaphore.h>
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <scsi/scsi_host.h>
44 45
45#include "aacraid.h" 46#include "aacraid.h"
46 47
@@ -581,6 +582,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
581 for (i = 0; i < upsg->count; i++) { 582 for (i = 0; i < upsg->count; i++) {
582 u64 addr; 583 u64 addr;
583 void* p; 584 void* p;
585 if (upsg->sg[i].count >
586 (dev->adapter_info.options &
587 AAC_OPT_NEW_COMM) ?
588 (dev->scsi_host_ptr->max_sectors << 9) :
589 65536) {
590 rcode = -EINVAL;
591 goto cleanup;
592 }
584 /* Does this really need to be GFP_DMA? */ 593 /* Does this really need to be GFP_DMA? */
585 p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); 594 p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA);
586 if(!p) { 595 if(!p) {
@@ -625,6 +634,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
625 for (i = 0; i < usg->count; i++) { 634 for (i = 0; i < usg->count; i++) {
626 u64 addr; 635 u64 addr;
627 void* p; 636 void* p;
637 if (usg->sg[i].count >
638 (dev->adapter_info.options &
639 AAC_OPT_NEW_COMM) ?
640 (dev->scsi_host_ptr->max_sectors << 9) :
641 65536) {
642 rcode = -EINVAL;
643 goto cleanup;
644 }
628 /* Does this really need to be GFP_DMA? */ 645 /* Does this really need to be GFP_DMA? */
629 p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); 646 p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
630 if(!p) { 647 if(!p) {
@@ -667,6 +684,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
667 for (i = 0; i < upsg->count; i++) { 684 for (i = 0; i < upsg->count; i++) {
668 uintptr_t addr; 685 uintptr_t addr;
669 void* p; 686 void* p;
687 if (usg->sg[i].count >
688 (dev->adapter_info.options &
689 AAC_OPT_NEW_COMM) ?
690 (dev->scsi_host_ptr->max_sectors << 9) :
691 65536) {
692 rcode = -EINVAL;
693 goto cleanup;
694 }
670 /* Does this really need to be GFP_DMA? */ 695 /* Does this really need to be GFP_DMA? */
671 p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); 696 p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
672 if(!p) { 697 if(!p) {
@@ -698,6 +723,14 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
698 for (i = 0; i < upsg->count; i++) { 723 for (i = 0; i < upsg->count; i++) {
699 dma_addr_t addr; 724 dma_addr_t addr;
700 void* p; 725 void* p;
726 if (upsg->sg[i].count >
727 (dev->adapter_info.options &
728 AAC_OPT_NEW_COMM) ?
729 (dev->scsi_host_ptr->max_sectors << 9) :
730 65536) {
731 rcode = -EINVAL;
732 goto cleanup;
733 }
701 p = kmalloc(upsg->sg[i].count, GFP_KERNEL); 734 p = kmalloc(upsg->sg[i].count, GFP_KERNEL);
702 if (!p) { 735 if (!p) {
703 dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 736 dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",