From: Gustavo Padovan <gustavo.pado...@collabora.co.uk>

The len member of struct sync_file_info was returning the size of the whole
buffer (struct sync_file_info + sync_fence_infos at the of it). This commit
change it to return only the size of the array of sync_fence_infos.

It also moves len to be right before the sync_fences_info field.

v2: fix check for name field (Maarten)

Signed-off-by: Gustavo Padovan <gustavo.padovan at collabora.co.uk>
---
 drivers/staging/android/sync.c      | 17 ++++++++++++-----
 drivers/staging/android/uapi/sync.h |  7 +++----
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index e301b55..d6cf89f 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -502,14 +502,20 @@ static int sync_fill_fence_info(struct fence *fence, void 
*data, int size)
 static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
                                        unsigned long arg)
 {
-       struct sync_file_info *info;
+       struct sync_file_info in, *info;
        __u32 size;
-       __u32 len = 0;
+       __u32 b_len, len = 0;
        int ret, i;

-       if (copy_from_user(&size, (void __user *)arg, sizeof(size)))
+       if (copy_from_user(&in, (void __user *)arg, sizeof(*info)))
                return -EFAULT;

+       if (in.status || in.num_fences || in.sync_fence_info ||
+           strcmp(in.name, "\0"))
+               return -EFAULT;
+
+       size = in.len;
+
        if (size < sizeof(struct sync_file_info))
                return -EINVAL;

@@ -527,8 +533,9 @@ static long sync_file_ioctl_fence_info(struct sync_file 
*sync_file,

        info->num_fences = sync_file->num_fences;

-       len = sizeof(struct sync_file_info) - sizeof(__u64);
+       b_len = sizeof(struct sync_file_info) - sizeof(__u64);

+       len = b_len;
        for (i = 0; i < sync_file->num_fences; ++i) {
                struct fence *fence = sync_file->cbs[i].fence;

@@ -540,7 +547,7 @@ static long sync_file_ioctl_fence_info(struct sync_file 
*sync_file,
                len += ret;
        }

-       info->len = len;
+       info->len = len - b_len;

        if (copy_to_user((void __user *)arg, info, len))
                ret = -EFAULT;
diff --git a/drivers/staging/android/uapi/sync.h 
b/drivers/staging/android/uapi/sync.h
index fc7fbcf..4e1d38b 100644
--- a/drivers/staging/android/uapi/sync.h
+++ b/drivers/staging/android/uapi/sync.h
@@ -42,19 +42,18 @@ struct sync_fence_info {

 /**
  * struct sync_file_info - data returned from fence info ioctl
- * @len:       ioctl caller writes the size of the buffer its passing in.
- *             ioctl returns length of sync_file_info returned to
- *             userspace including pt_info.
  * @name:      name of fence
  * @status:    status of fence. 1: signaled 0:active <0:error
  * @num_fences number of fences in the sync_file
+ * @len:       ioctl caller writes the size of the buffer its passing in.
+ *             ioctl returns length of all fence_infos summed.
  * @sync_fence_info: array of sync_fence_info for every fence in the sync_file
  */
 struct sync_file_info {
-       __u32   len;
        char    name[32];
        __s32   status;
        __u32   num_fences;
+       __u32   len;

        __u64   sync_fence_info;
 };
-- 
2.5.0

Reply via email to