[PATCH v3 08/11] staging/android: make info->len return only size of sync_fence_info array

From: Gustavo Padovan
Date: Wed Feb 03 2016 - 08:29:50 EST


From: Gustavo Padovan <gustavo.padovan@xxxxxxxxxxxxxxx>

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@xxxxxxxxxxxxxxx>
---
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