[COMMON] g2d: fix the compat ioctl
authorHyesoo Yu <hyesoo.yu@samsung.com>
Tue, 27 Mar 2018 10:57:16 +0000 (19:57 +0900)
committerJanghyuck Kim <janghyuck.kim@samsung.com>
Mon, 23 Jul 2018 05:39:33 +0000 (14:39 +0900)
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 <hyesoo.yu@samsung.com>
drivers/gpu/exynos/g2d/g2d_drv.c

index a3ef84183eb5a463166d44fc7309fed01d168eb4..178458c7e5900cdef5a7a6de66af185c9200bcc2 100644 (file)
@@ -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);
        }