summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chant <achant@google.com>2019-07-25 12:04:48 -0700
committerjuyuchen <juyuchen@google.com>2019-07-27 02:38:26 +0800
commita8840fb476279fcef4f3710fd2e650b592b8d1ad (patch)
tree119bb89e2bcd95c3ceec6d3cb7d68382e3f3181f
parent1b1e665ff6ecc7a1283bf0244f8e117b218fb54f (diff)
downloadmsm-extra-a8840fb476279fcef4f3710fd2e650b592b8d1ad.tar.gz
audio: fixup crus_sp_compat_ioctl
crus_sp_ioctl_header needs to be re-allocated in crus_sp_compat_ioctl since the size of the structure is different between 32-bit and 64-bit callers. Also fixup the contained userspace pointer with compat_ptr(). Bug: 135130450 Bug: 135129430 Test: The calibration data is good to send to library and re-calibration works. Change-Id: Ie2c2473bf5ac061fd18426ae8c69b6dbf1895cda Signed-off-by: Andrew Chant <achant@google.com> Signed-off-by: juyuchen <juyuchen@google.com>
-rw-r--r--asoc/msm-cirrus-playback.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/asoc/msm-cirrus-playback.c b/asoc/msm-cirrus-playback.c
index a4c529ad..697b26f4 100644
--- a/asoc/msm-cirrus-playback.c
+++ b/asoc/msm-cirrus-playback.c
@@ -1422,13 +1422,48 @@ static long crus_sp_ioctl(struct file *f,
return crus_sp_shared_ioctl(f, cmd, (void __user *)arg);
}
+struct compat_crus_sp_ioctl_header {
+ uint32_t size;
+ uint32_t module_id;
+ uint32_t param_id;
+ uint32_t data_length;
+ compat_caddr_t data;
+};
+
static long crus_sp_compat_ioctl(struct file *f,
unsigned int cmd, unsigned long arg)
{
unsigned int cmd64;
+ struct compat_crus_sp_ioctl_header __user *ua32;
+ struct crus_sp_ioctl_header __user *ua;
+ compat_caddr_t __user ua32_data;
+ void __user *ua_data;
+ uint32_t ua32_size, ua_size;
pr_info("%s\n", __func__);
+ ua32 = compat_ptr(arg);
+ if (get_user(ua32_size, (uint32_t __user*)&ua32->size))
+ return -EFAULT;
+ if (ua32_size != sizeof(*ua32))
+ return -EINVAL;
+
+ ua_size = sizeof(*ua);
+ ua = compat_alloc_user_space(ua_size);
+ if (!ua)
+ return -ENOMEM;
+
+ /* Copy everything but data, then fixup size & data. */
+ if (copy_in_user(ua, ua32, sizeof(*ua32) - sizeof(ua32->data)))
+ return -EFAULT;
+ if (put_user(ua_size, (uint32_t __user*)&ua->size))
+ return -EFAULT;
+ if (get_user(ua32_data, (compat_caddr_t __user*)&ua32->data))
+ return -EFAULT;
+ ua_data = compat_ptr(ua32_data);
+ if (put_user(ua_data, (void* __user*)&ua->data))
+ return -EFAULT;
+
switch (cmd) {
case CRUS_SP_IOCTL_GET32:
cmd64 = CRUS_SP_IOCTL_GET;
@@ -1447,7 +1482,7 @@ static long crus_sp_compat_ioctl(struct file *f,
return -EINVAL;
}
- return crus_sp_shared_ioctl(f, cmd64, compat_ptr(arg));
+ return crus_sp_shared_ioctl(f, cmd64, ua);
}
static int crus_sp_open(struct inode *inode, struct file *f)