From f7b2532f780c02de1adc8f4d4da6eed90afcad28 Mon Sep 17 00:00:00 2001 From: Hyesoo Yu Date: Tue, 27 Mar 2018 19:57:16 +0900 Subject: [PATCH] [COMMON] g2d: fix the compat ioctl The variable of buffer is corrupted while looping, so incorrect data is written to the user's area in the loop. And user address of buffer is possible to be corrupted when union variable is not initialized, so fix it. Change-Id: I5bb38eb4dd548a868153a32ebd5b31a76a20f112 Signed-off-by: Hyesoo Yu --- drivers/gpu/exynos/g2d/g2d_drv.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/exynos/g2d/g2d_drv.c b/drivers/gpu/exynos/g2d/g2d_drv.c index a3ef84183eb5..178458c7e590 100644 --- a/drivers/gpu/exynos/g2d/g2d_drv.c +++ b/drivers/gpu/exynos/g2d/g2d_drv.c @@ -520,7 +520,7 @@ static int g2d_compat_get_layerdata(struct device *dev, struct g2d_layer_data __user *img, struct compat_g2d_layer_data __user *cimg) { - __u32 uw; + __u32 uw, num_buffers, buftype; __s32 sw; compat_ulong_t l; unsigned int i; @@ -530,18 +530,21 @@ static int g2d_compat_get_layerdata(struct device *dev, ret |= put_user(uw, &img->flags); ret |= get_user(sw, &cimg->fence); ret |= put_user(sw, &img->fence); - ret |= get_user(uw, &cimg->buffer_type); - ret |= put_user(uw, &img->buffer_type); - ret |= get_user(uw, &cimg->num_buffers); - ret |= put_user(uw, &img->num_buffers); - - for (i = 0; i < uw; i++) { /* uw contains num_buffers */ - ret |= get_user(l, &cimg->buffer[i].userptr); - ret |= put_user(l, &img->buffer[i].userptr); - ret |= get_user(uw, &cimg->buffer[i].dmabuf.offset); - ret |= put_user(uw, &img->buffer[i].dmabuf.offset); - ret |= get_user(sw, &cimg->buffer[i].dmabuf.fd); - ret |= put_user(sw, &img->buffer[i].dmabuf.fd); + ret |= get_user(buftype, &cimg->buffer_type); + ret |= put_user(buftype, &img->buffer_type); + ret |= get_user(num_buffers, &cimg->num_buffers); + ret |= put_user(num_buffers, &img->num_buffers); + + for (i = 0; i < num_buffers; i++) { + if (buftype == G2D_BUFTYPE_DMABUF) { + ret |= get_user(uw, &cimg->buffer[i].dmabuf.offset); + ret |= put_user(uw, &img->buffer[i].dmabuf.offset); + ret |= get_user(sw, &cimg->buffer[i].dmabuf.fd); + ret |= put_user(sw, &img->buffer[i].dmabuf.fd); + } else { + ret |= get_user(l, &cimg->buffer[i].userptr); + ret |= put_user(l, &img->buffer[i].userptr); + } ret |= get_user(uw, &cimg->buffer[i].length); ret |= put_user(uw, &img->buffer[i].length); } -- 2.20.1