megaraid_mbox: fix Oops on SG_IO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch fixes an Oops in megaraid_mbox that happens whena MODE_SENSE command for a logical drive is started viaioctl(SG_IO).
The problem only occures, if the buffer specified by the userto receive the mode data resides in highmem and if the bufferis aligned for direct dma (no bounce buffer necessary).megaraid_mbox emulates the MODE_SENSE command and writes thedata using memset() directly into user buffer. If the bufferis at a currently unmapped highmem page, this leads to anOops.
The second hunk of the patch is untested! AFAICS, it shouldfix the same problem at another place. I'm not shure, butmaybe other LLDs must be fixed similarly, as they also seemto call sg_virt() without doing kmap before.
Please CC me, I'm not on the list.

Signed-off-by: Bodo Stroesser <bstroesser@xxxxxxxxxxxxxxxxxxx>
------ linux-2.6.27.7-9/drivers/scsi/megaraid/megaraid_mbox.c.orig	2008-10-10 00:13:53.000000000 +0200+++ linux-2.6.27.7-9/drivers/scsi/megaraid/megaraid_mbox.c	2009-02-03 15:01:56.000000000 +0100@@ -1580,13 +1580,20 @@ megaraid_mbox_build_cmd(adapter_t *adapt 		case MODE_SENSE: 		{ 			struct scatterlist	*sgl;-			caddr_t			vaddr;+			struct page		*pg;+			unsigned char		*vaddr;+			unsigned long		flags;  			sgl = scsi_sglist(scp);-			if (sg_page(sgl)) {-				vaddr = (caddr_t) sg_virt(&sgl[0]);+			pg = sg_page(sgl);+			if (pg) {+				local_irq_save(flags);+				vaddr = kmap_atomic(pg, KM_BIO_SRC_IRQ) + sgl->offset;  				memset(vaddr, 0, scp->cmnd[4]);++				kunmap_atomic(vaddr, KM_BIO_SRC_IRQ);+				local_irq_restore(flags); 			} 			else { 				con_log(CL_ANN, (KERN_WARNING@@ -2324,9 +2331,20 @@ megaraid_mbox_dpc(unsigned long devp) 		if (scp->cmnd[0] == INQUIRY && status == 0 && islogical == 0 				&& IS_RAID_CH(raid_dev, scb->dev_channel)) { +			struct page		*pg;+			unsigned char		*vaddr;+			unsigned long		flags;+ 			sgl = scsi_sglist(scp);-			if (sg_page(sgl)) {-				c = *(unsigned char *) sg_virt(&sgl[0]);+			pg = sg_page(sgl);+			if (pg) {+				local_irq_save(flags);+				vaddr = kmap_atomic(pg, KM_BIO_SRC_IRQ) + sgl->offset;++				c = *vaddr;++				kunmap_atomic(vaddr, KM_BIO_SRC_IRQ);+				local_irq_restore(flags); 			} else { 				con_log(CL_ANN, (KERN_WARNING 						 "megaraid mailbox: invalid sg:%d\n",ÿôèº{.nÇ+?·?®?­?+%?Ëÿ±éݶ¥?wÿº{.nÇ+?·¥?{±þÇ,?ø§¶?¡Ü¨}©?²Æ zÚ&j:+v?¨þø¯ù®w¥þ?à2?Þ?¨è­Ú&¢)ß¡«a¶Úÿÿûàz¿äz¹Þ?ú+?ù???Ý¢jÿ?wèþf


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux