From 3b1175c71f86b278ce688c9018b795b22deb0c38 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 19 Oct 2010 07:57:48 +0200 Subject: [PATCH] --- yaml --- r: 221950 b: refs/heads/master c: e9f25689a86570c30d3f101b1f9834a579bed2e5 h: refs/heads/master v: v3 --- [refs] | 2 +- .../intel_sst/intel_sst_app_interface.c | 93 ++++++++++++------- 2 files changed, 58 insertions(+), 37 deletions(-) diff --git a/[refs] b/[refs] index 934447444282..d8fb98299cfd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bc704e31edc723a84c2469f26aa0279e1ddb948e +refs/heads/master: e9f25689a86570c30d3f101b1f9834a579bed2e5 diff --git a/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c b/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c index 8390aa793b7b..d20724d3b68d 100644 --- a/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -1105,62 +1105,83 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_STREAM_DECODE): { - struct snd_sst_dbufs *param = - (struct snd_sst_dbufs *)arg, dbufs_local; - int i; + struct snd_sst_dbufs param; + struct snd_sst_dbufs dbufs_local; struct snd_sst_buffs ibufs, obufs; - struct snd_sst_buff_entry ibuf_temp[param->ibufs->entries], - obuf_temp[param->obufs->entries]; + struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp; + char __user *dest; pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; } - if (!param) { - retval = -EINVAL; + if (copy_from_user(¶m, (void __user *)arg, + sizeof(param))) { + retval = -EFAULT; break; } - dbufs_local.input_bytes_consumed = param->input_bytes_consumed; + dbufs_local.input_bytes_consumed = param.input_bytes_consumed; dbufs_local.output_bytes_produced = - param->output_bytes_produced; - dbufs_local.ibufs = &ibufs; - dbufs_local.obufs = &obufs; - dbufs_local.ibufs->entries = param->ibufs->entries; - dbufs_local.ibufs->type = param->ibufs->type; - dbufs_local.obufs->entries = param->obufs->entries; - dbufs_local.obufs->type = param->obufs->type; - - dbufs_local.ibufs->buff_entry = ibuf_temp; - for (i = 0; i < dbufs_local.ibufs->entries; i++) { - ibuf_temp[i].buffer = - param->ibufs->buff_entry[i].buffer; - ibuf_temp[i].size = - param->ibufs->buff_entry[i].size; + param.output_bytes_produced; + + if (copy_from_user(&ibufs, param.ibufs, sizeof(ibufs))) { + retval = -EFAULT; + break; + } + if (copy_from_user(&obufs, param.obufs, sizeof(obufs))) { + retval = -EFAULT; + break; + } + + ibuf_tmp = kcalloc(ibufs.entries, sizeof(*ibuf_tmp), GFP_KERNEL); + obuf_tmp = kcalloc(obufs.entries, sizeof(*obuf_tmp), GFP_KERNEL); + if (!ibuf_tmp || !obuf_tmp) { + retval = -ENOMEM; + goto free_iobufs; + } + + if (copy_from_user(ibuf_tmp, ibufs.buff_entry, + ibufs.entries * sizeof(*ibuf_tmp))) { + retval = -EFAULT; + goto free_iobufs; } - dbufs_local.obufs->buff_entry = obuf_temp; - for (i = 0; i < dbufs_local.obufs->entries; i++) { - obuf_temp[i].buffer = - param->obufs->buff_entry[i].buffer; - obuf_temp[i].size = - param->obufs->buff_entry[i].size; + ibufs.buff_entry = ibuf_tmp; + dbufs_local.ibufs = &ibufs; + + if (copy_from_user(obuf_tmp, obufs.buff_entry, + obufs.entries * sizeof(*obuf_tmp))) { + retval = -EFAULT; + goto free_iobufs; } + obufs.buff_entry = obuf_tmp; + dbufs_local.obufs = &obufs; + retval = sst_decode(str_id, &dbufs_local); - if (retval) - retval = -EAGAIN; - if (copy_to_user(¶m->input_bytes_consumed, + if (retval) { + retval = -EAGAIN; + goto free_iobufs; + } + + dest = (char *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed); + if (copy_to_user(dest, &dbufs_local.input_bytes_consumed, sizeof(unsigned long long))) { - retval = -EFAULT; - break; + retval = -EFAULT; + goto free_iobufs; } - if (copy_to_user(¶m->output_bytes_produced, + + dest = (char *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed); + if (copy_to_user(dest, &dbufs_local.output_bytes_produced, sizeof(unsigned long long))) { - retval = -EFAULT; - break; + retval = -EFAULT; + goto free_iobufs; } +free_iobufs: + kfree(ibuf_tmp); + kfree(obuf_tmp); break; }