diff options
author | Tomas Henzl <thenzl@redhat.com> | 2010-02-11 18:01:50 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-26 14:27:06 -0700 |
commit | 4531e534fec25888d8645ef9b2ecf6146e96c2a7 (patch) | |
tree | deae1b2c0bff8898d6cd7ec2611b9ab4ffa4fb1d /drivers | |
parent | 1ae9213b109c56470b79df5af1e36e780916eb57 (diff) |
megaraid_sas: fix for 32bit apps
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 4c3f1247ebff..342df4aaa074 100644 --- 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(struct file *file, unsigned long arg) 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(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; + /* + * 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, |