summaryrefslogtreecommitdiff
path: root/drivers/mxc/sim
diff options
context:
space:
mode:
authorGao Pan <pandy.gao@nxp.com>2017-04-13 14:58:03 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:26:14 +0800
commit7c049d2c0d995cdb74106214eaaf67ed2d18986b (patch)
treee0a15ae0366c2cfedeb97ba47309c442e3300b9f /drivers/mxc/sim
parentb4ad0d4ec42565225473e5300881c116d9ec56f7 (diff)
MLK-14642 imx: sim: fix segment fault caused by user address access
Kernel space cannot access user space memory directly. In fact, the issue always exited. Since 4.4, the kernel handle the action as page abort. Signed-off-by: Gao Pan <pandy.gao@nxp.com> Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Diffstat (limited to 'drivers/mxc/sim')
-rwxr-xr-xdrivers/mxc/sim/imx_sim.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/mxc/sim/imx_sim.c b/drivers/mxc/sim/imx_sim.c
index b527142f0337..d33c11a9ecbb 100755
--- a/drivers/mxc/sim/imx_sim.c
+++ b/drivers/mxc/sim/imx_sim.c
@@ -1299,6 +1299,9 @@ static long sim_ioctl(struct file *file,
u32 delay;
u32 copy_cnt, val;
unsigned long flags;
+ unsigned char __user *atr_buffer;
+ unsigned char __user *xmt_buffer;
+ unsigned char __user *rcv_buffer;
struct sim_t *sim = (struct sim_t *) file->private_data;
@@ -1341,8 +1344,8 @@ static long sim_ioctl(struct file *file,
break;
}
- ret = copy_to_user(((sim_atr_t *)arg)->atr_buffer, sim->rcv_buffer,
- sim->rcv_count);
+ __get_user(atr_buffer, &((sim_atr_t __user *)arg)->atr_buffer);
+ ret = copy_to_user(atr_buffer, sim->rcv_buffer, sim->rcv_count);
if (ret) {
pr_err("ATR ACCESS buffer Error %d %d\n", sim->rcv_count, ret);
errval = -SIM_E_ACCESS;
@@ -1389,8 +1392,9 @@ static long sim_ioctl(struct file *file,
errval = -EINVAL;
break;
}
- ret = copy_from_user(sim->xmt_buffer, (((sim_xmt_t *)arg)->xmt_buffer),
- sim->xmt_remaining);
+
+ __get_user(xmt_buffer, &((sim_xmt_t *)arg)->xmt_buffer);
+ ret = copy_from_user(sim->xmt_buffer, xmt_buffer, sim->xmt_remaining);
if (ret) {
pr_err("Copy Error\n");
@@ -1526,8 +1530,8 @@ copy_data:
break;
}
- ret = copy_to_user(((sim_rcv_t *)arg)->rcv_buffer, &sim->rcv_buffer[sim->rcv_head],
- copy_cnt);
+ __get_user(rcv_buffer, &((sim_rcv_t *)arg)->rcv_buffer);
+ ret = copy_to_user(rcv_buffer, &sim->rcv_buffer[sim->rcv_head], copy_cnt);
if (ret) {
pr_err("ATR ACCESS Error\n");
errval = -SIM_E_ACCESS;