Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3496

kernel-2.6.18-194.11.1.el5.src.rpm

From: Tomas Henzl <thenzl@redhat.com>
Date: Mon, 1 Feb 2010 16:53:00 -0500
Subject: [scsi] megaraid: fix 32-bit apps on 64-bit kernel
Message-id: <4B6706EC.8060400@redhat.com>
Patchwork-id: 23054
O-Subject: Re: [RHEL5.5 PATCH] bz518243 megaraid: fix 32bit apps
Bugzilla: 518243

bz#518243

This should resolve a problem introduced by the last
driver update to v4.17 - also bz518243.
Part of this patch in function megasas_mgmt_fw_ioctl
should resolve a problem with a 64bit pointer
stored in a u32.
-      u32 *sense_ptr;
+      unsigned long *sense_ptr;

...
          sense_ptr =
-            (u32 *) ((unsigned long)cmd->frame + ioc->sense_off);
+            (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
          *sense_ptr = sense_handle;
...
-      sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
-                             ioc->sense_off);
+      sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
+                       ioc->sense_off);

       if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
                        sense, ioc->sense_len)) {
...
This on the other side caused problems for 32bit
programs in 64 bit os, for example Dell's 'open manage'(omsa).

Patch below is tested by customer on 64bit, he also verified the
omsa functionality.
I've verified that there are no error messages with 32, 64, and PAE kernel.

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index e48d37b..8965842 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -3966,6 +3966,8 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
 	    compat_alloc_user_space(sizeof(struct megasas_iocpacket));
 	int i;
 	int error = 0;
+	compat_uptr_t ptr;
+	u8 *raw_ptr;
 
 	if (clear_user(ioc, sizeof(*ioc)))
 		return -EFAULT;
@@ -3978,9 +3980,14 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
 	    copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
 		return -EFAULT;
 
-	for (i = 0; i < MAX_IOCTL_SGE; i++) {
-		compat_uptr_t ptr;
+	if (ioc->sense_len) {
+		raw_ptr = ioc->frame.raw + ioc->sense_off;
+		if (get_user(ptr, (compat_uptr_t *)raw_ptr) ||
+		    put_user(ptr, (unsigned long *)raw_ptr))
+			return -EFAULT;
+	}
 
+	for (i = 0; i < MAX_IOCTL_SGE; i++) {
 		if (get_user(ptr, &cioc->sgl[i].iov_base) ||
 		    put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
 		    copy_in_user(&ioc->sgl[i].iov_len,