| From b3dc1a212e5167984616445990c76056034f8eeb Mon Sep 17 00:00:00 2001 |
| From: Tomas Henzl <thenzl@redhat.com> |
| Date: Thu, 11 Feb 2010 18:01:50 +0100 |
| Subject: [SCSI] megaraid_sas: fix for 32bit apps |
| |
| From: Tomas Henzl <thenzl@redhat.com> |
| |
| commit b3dc1a212e5167984616445990c76056034f8eeb upstream. |
| |
| It looks like this patch - |
| |
| commit 7b2519afa1abd1b9f63aa1e90879307842422dae |
| Author: Yang, Bo <Bo.Yang@lsi.com> |
| Date: Tue Oct 6 14:52:20 2009 -0600 |
| |
| [SCSI] megaraid_sas: fix 64 bit sense pointer truncation |
| |
| has caused a problem for 32bit programs with 64bit os - |
| |
| http://bugzilla.kernel.org/show_bug.cgi?id=15001 |
| |
| fix by converting the user space 32bit pointer to a 64 bit one when |
| needed. |
| |
| [jejb: fix up some 64 bit warnings] |
| Signed-off-by: Tomas Henzl <thenzl@redhat.com> |
| Cc: Bo Yang <Bo.Yang@lsi.com> |
| Signed-off-by: James Bottomley <James.Bottomley@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/scsi/megaraid/megaraid_sas.c | 18 ++++++++++++++++-- |
| 1 file changed, 16 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/scsi/megaraid/megaraid_sas.c |
| +++ b/drivers/scsi/megaraid/megaraid_sas.c |
| @@ -3292,6 +3292,7 @@ static int megasas_mgmt_compat_ioctl_fw( |
| compat_alloc_user_space(sizeof(struct megasas_iocpacket)); |
| int i; |
| int error = 0; |
| + compat_uptr_t ptr; |
| |
| if (clear_user(ioc, sizeof(*ioc))) |
| return -EFAULT; |
| @@ -3304,9 +3305,22 @@ static int megasas_mgmt_compat_ioctl_fw( |
| 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; |
| + /* |
| + * The sense_ptr is used in megasas_mgmt_fw_ioctl only when |
| + * sense_len is not null, so prepare the 64bit value under |
| + * the same condition. |
| + */ |
| + if (ioc->sense_len) { |
| + void __user **sense_ioc_ptr = |
| + (void __user **)(ioc->frame.raw + ioc->sense_off); |
| + compat_uptr_t *sense_cioc_ptr = |
| + (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off); |
| + if (get_user(ptr, sense_cioc_ptr) || |
| + put_user(compat_ptr(ptr), sense_ioc_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, |