From 48683e52caf555cd6ef76384542d7b940d911d6e Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Mon, 28 May 2018 22:51:33 +0200 Subject: Copy surface ioctl params from user --- surface.c | 179 ++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 50 deletions(-) (limited to 'surface.c') diff --git a/surface.c b/surface.c index f4fa64f..82d9756 100644 --- a/surface.c +++ b/surface.c @@ -330,45 +330,80 @@ error_data: long draw_lines(struct file *filp, unsigned long arg) { struct surface_data *surface_data; - struct doomdev_surf_ioctl_draw_lines *param; + struct doomdev_surf_ioctl_draw_lines param; struct doomdev_line *lines; + struct doomdev_line line; int i; + int err; + int not_copied; surface_data = filp->private_data; - param = (struct doomdev_surf_ioctl_draw_lines *) arg; - lines = (struct doomdev_line *) param->lines_ptr; + not_copied = copy_from_user(¶m, (void __iomem *) arg, sizeof(param)); + if (not_copied) { + err = -EFAULT; + goto error_param; + } + + lines = (struct doomdev_line *) param.lines_ptr; mutex_lock(&surface_data->doom_data->cmd_mutex); - for (i = 0; i < param->lines_num; i++) { - draw_line(surface_data, lines[i]); + for (i = 0; i < param.lines_num; i++) { + not_copied = copy_from_user(&line, (void __iomem *) &lines[i], + sizeof(line)); + if (not_copied) { + goto error_copy; + } + + draw_line(surface_data, &lines[i]); } +error_copy: + err = i; mutex_unlock(&surface_data->doom_data->cmd_mutex); - return param->lines_num; +error_param: + return err; } long fill_rects(struct file *filp, unsigned long arg) { struct surface_data *surface_data; - struct doomdev_surf_ioctl_fill_rects *param; + struct doomdev_surf_ioctl_fill_rects param; struct doomdev_fill_rect *rects; + struct doomdev_fill_rect rect; int i; + int not_copied; + int err; surface_data = filp->private_data; - param = (struct doomdev_surf_ioctl_fill_rects *) arg; - rects = (struct doomdev_fill_rect *) param->rects_ptr; + not_copied = copy_from_user(¶m, (void __iomem *) arg, sizeof(param)); + if (not_copied) { + err = -EFAULT; + goto error_param; + } + + rects = (struct doomdev_fill_rect *) param.rects_ptr; mutex_lock(&surface_data->doom_data->cmd_mutex); - for (i = 0; i < param->rects_num; i++) { - fill_rect(surface_data, rects[i]); + for (i = 0; i < param.rects_num; i++) { + not_copied = copy_from_user(&rect, (void __iomem *) &rects[i], + sizeof(rect)); + if (not_copied) { + goto error_copy; + } + + fill_rect(surface_data, &rect); } +error_copy: + err = i; + mutex_unlock(&surface_data->doom_data->cmd_mutex); - return param->rects_num; +error_param: + return err; } struct file_operations surface_fops; @@ -377,17 +412,24 @@ long copy_rects(struct file *filp, unsigned long arg) { struct surface_data *dst_data; struct surface_data *src_data; - struct doomdev_surf_ioctl_copy_rects *param; + struct doomdev_surf_ioctl_copy_rects param; struct doomdev_copy_rect *rects; + struct doomdev_copy_rect rect; struct fd src_fds; int i; int err; + int not_copied; dst_data = filp->private_data; - param = (struct doomdev_surf_ioctl_copy_rects *) arg; - rects = (struct doomdev_copy_rect *) param->rects_ptr; + not_copied = copy_from_user(¶m, (void __iomem *) arg, sizeof(param)); + if (not_copied) { + err = -EFAULT; + goto error_param; + } - src_fds = fdget(param->surf_src_fd); + rects = (struct doomdev_copy_rect *) param.rects_ptr; + + src_fds = fdget(param.surf_src_fd); if (src_fds.file->f_op != &surface_fops) { err = -EINVAL; goto error_fdget; @@ -401,51 +443,62 @@ long copy_rects(struct file *filp, unsigned long arg) mutex_lock(&dst_data->doom_data->cmd_mutex); - for (i = 0; i < param->rects_num; i++) { - copy_rect(dst_data, src_data, rects[i]); + for (i = 0; i < param.rects_num; i++) { + not_copied = copy_from_user(&rect, (void __iomem *) &rects[i], + sizeof(rect)); + if (not_copied) { + goto error_copy; + } + + copy_rect(dst_data, src_data, &rect); } - err = param->rects_num; +error_copy: + err = i; mutex_unlock(&dst_data->doom_data->cmd_mutex); error_fdget: fdput(src_fds); +error_param: return err; } long draw_columns(struct file *filp, unsigned long arg) { - struct doomdev_surf_ioctl_draw_columns *param; + struct doomdev_surf_ioctl_draw_columns param; struct surface_data *surface_data; struct texture_data *texture_data; struct colors_data *colors_data; struct colors_data *trans_data; struct doomdev_column *columns; + struct doomdev_column column; struct fd texture_fds; struct fd colors_fds; struct fd trans_fds; - uint8_t flags; bool got_colors = false; bool got_trans = false; bool got_texture = false; + int not_copied; int i; int err; surface_data = filp->private_data; - param = (struct doomdev_surf_ioctl_draw_columns *) arg; - - flags = param->draw_flags; + not_copied = copy_from_user(¶m, (void __iomem *) arg, sizeof(param)); + if (not_copied) { + err = -EFAULT; + goto error_param; + } - if (flags & DOOMDEV_DRAW_FLAGS_FUZZ || - flags & DOOMDEV_DRAW_FLAGS_COLORMAP) { - if (flags & DOOMDEV_DRAW_FLAGS_FUZZ) { - flags = DOOMDEV_DRAW_FLAGS_FUZZ; + if (param.draw_flags & DOOMDEV_DRAW_FLAGS_FUZZ || + param.draw_flags & DOOMDEV_DRAW_FLAGS_COLORMAP) { + if (param.draw_flags & DOOMDEV_DRAW_FLAGS_FUZZ) { + param.draw_flags = DOOMDEV_DRAW_FLAGS_FUZZ; } - colors_fds = fdget(param->colormaps_fd); + colors_fds = fdget(param.colormaps_fd); got_colors = true; if (colors_fds.file->f_op != &colors_fops) { err = -EINVAL; @@ -459,8 +512,8 @@ long draw_columns(struct file *filp, unsigned long arg) } } - if (flags & DOOMDEV_DRAW_FLAGS_TRANSLATE) { - trans_fds = fdget(param->translations_fd); + if (param.draw_flags & DOOMDEV_DRAW_FLAGS_TRANSLATE) { + trans_fds = fdget(param.translations_fd); got_trans = true; if (trans_fds.file->f_op != &colors_fops) { err = -EINVAL; @@ -474,7 +527,7 @@ long draw_columns(struct file *filp, unsigned long arg) } } - texture_fds = fdget(param->texture_fd); + texture_fds = fdget(param.texture_fd); got_texture = true; if (texture_fds.file->f_op != &texture_fops) { err = -EINVAL; @@ -487,16 +540,23 @@ long draw_columns(struct file *filp, unsigned long arg) goto error_fdget; } - columns = (struct doomdev_column *) param->columns_ptr; + columns = (struct doomdev_column *) param.columns_ptr; mutex_lock(&surface_data->doom_data->cmd_mutex); - for (i = 0; i < param->columns_num; i++) { - draw_column(surface_data, texture_data, columns[i], colors_data, - trans_data, flags, param->translation_idx); + for (i = 0; i < param.columns_num; i++) { + not_copied = copy_from_user(&column, + (void __iomem *) &columns[i], sizeof(column)); + if (not_copied) { + goto error_copy; + } + + draw_column(surface_data, texture_data, &column, colors_data, + trans_data, param.draw_flags, param.translation_idx); } - err = param->columns_num; +error_copy: + err = i; mutex_unlock(&surface_data->doom_data->cmd_mutex); @@ -514,24 +574,31 @@ error_fdget: fdput(trans_fds); } - return param->columns_num; +error_param: + return err; } long draw_spans(struct file *filp, unsigned long arg) { - struct doomdev_surf_ioctl_draw_spans *param; + struct doomdev_surf_ioctl_draw_spans param; struct surface_data *surface_data; struct flat_data *flat_data; struct doomdev_span *spans; + struct doomdev_span span; struct fd flat_fds; int i; int err; + int not_copied; surface_data = filp->private_data; - param = (struct doomdev_surf_ioctl_draw_spans *) arg; + not_copied = copy_from_user(¶m, (void __iomem *) arg, sizeof(param)); + if (not_copied) { + err = -EFAULT; + goto error_param; + } - flat_fds = fdget(param->flat_fd); + flat_fds = fdget(param.flat_fd); if (flat_fds.file->f_op != &flat_fops) { err = -EINVAL; goto error_fdget; @@ -543,37 +610,49 @@ long draw_spans(struct file *filp, unsigned long arg) goto error_fdget; } - spans = (struct doomdev_span *) param->spans_ptr; + spans = (struct doomdev_span *) param.spans_ptr; mutex_lock(&surface_data->doom_data->cmd_mutex); - for (i = 0; i < param->spans_num; i++) { - draw_span(surface_data, flat_data, spans[i]); + for (i = 0; i < param.spans_num; i++) { + not_copied = copy_from_user(&span, (void __iomem *) &spans[i], + sizeof(span)); + if (not_copied) { + goto error_copy; + } + + draw_span(surface_data, flat_data, &span); } - err = param->spans_num; +error_copy: + err = i; mutex_unlock(&surface_data->doom_data->cmd_mutex); error_fdget: fdput(flat_fds); - +error_param: return err; } long do_draw_background(struct file *filp, unsigned long arg) { - struct doomdev_surf_ioctl_draw_background *param; + struct doomdev_surf_ioctl_draw_background param; struct surface_data *surface_data; struct flat_data *flat_data; struct fd flat_fds; int err = 0; + int not_written; surface_data = filp->private_data; - param = (struct doomdev_surf_ioctl_draw_background *) arg; + not_written = copy_from_user(¶m, (void __iomem *) arg, sizeof(param)); + if (not_written) { + err = -EFAULT; + goto error_param; + } - flat_fds = fdget(param->flat_fd); + flat_fds = fdget(param.flat_fd); if (flat_fds.file->f_op != &flat_fops) { err = -EINVAL; goto error_fdget; @@ -593,7 +672,7 @@ long do_draw_background(struct file *filp, unsigned long arg) error_fdget: fdput(flat_fds); - +error_param: return err; } -- cgit v1.2.3