m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-28 22:51:33 +0200
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-28 22:51:33 +0200
commit48683e52caf555cd6ef76384542d7b940d911d6e (patch)
tree5fe95a450a3f853ebdce05db66402fee8a520e5a
parent34d2c2e0137b3ad637a3cfa9c7afbdf636fc6384 (diff)
Copy surface ioctl params from user
-rw-r--r--harddoomdev.c60
-rw-r--r--harddoomdev.h10
-rw-r--r--surface.c179
3 files changed, 164 insertions, 85 deletions
diff --git a/harddoomdev.c b/harddoomdev.c
index fc1f0e4..4a17001 100644
--- a/harddoomdev.c
+++ b/harddoomdev.c
@@ -194,68 +194,68 @@ void set_draw_params(struct doom_data *doom_data, uint8_t flags)
}
}
-void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect rect)
+void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect *rect)
{
set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
set_surf_dims(surface_data->doom_data, surface_data->width, surface_data->height);
- set_xy_a(surface_data->doom_data, rect.pos_dst_x, rect.pos_dst_y);
- set_fill_color(surface_data->doom_data, rect.color);
+ set_xy_a(surface_data->doom_data, rect->pos_dst_x, rect->pos_dst_y);
+ set_fill_color(surface_data->doom_data, rect->color);
- send_command(surface_data->doom_data, HARDDOOM_CMD_FILL_RECT(rect.width, rect.height));
+ send_command(surface_data->doom_data, HARDDOOM_CMD_FILL_RECT(rect->width, rect->height));
}
-void draw_line(struct surface_data *surface_data, struct doomdev_line line)
+void draw_line(struct surface_data *surface_data, struct doomdev_line *line)
{
set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
set_surf_dims(surface_data->doom_data, surface_data->width, surface_data->height);
- set_xy_a(surface_data->doom_data, line.pos_a_x, line.pos_a_y);
- set_xy_b(surface_data->doom_data, line.pos_b_x, line.pos_b_y);
- set_fill_color(surface_data->doom_data, line.color);
+ set_xy_a(surface_data->doom_data, line->pos_a_x, line->pos_a_y);
+ set_xy_b(surface_data->doom_data, line->pos_b_x, line->pos_b_y);
+ set_fill_color(surface_data->doom_data, line->color);
send_command(surface_data->doom_data, HARDDOOM_CMD_DRAW_LINE);
}
void copy_rect(struct surface_data *dst_data, struct surface_data *src_data,
- struct doomdev_copy_rect rect)
+ struct doomdev_copy_rect *rect)
{
set_surf_dst_pt(dst_data->doom_data, dst_data->page_table_dev);
set_surf_src_pt(dst_data->doom_data, src_data->page_table_dev);
set_surf_dims(dst_data->doom_data, dst_data->width, dst_data->height);
- set_xy_a(dst_data->doom_data, rect.pos_dst_x, rect.pos_dst_y);
- set_xy_b(dst_data->doom_data, rect.pos_src_x, rect.pos_src_y);
+ set_xy_a(dst_data->doom_data, rect->pos_dst_x, rect->pos_dst_y);
+ set_xy_b(dst_data->doom_data, rect->pos_src_x, rect->pos_src_y);
- send_command(dst_data->doom_data, HARDDOOM_CMD_COPY_RECT(rect.width, rect.height));
+ send_command(dst_data->doom_data, HARDDOOM_CMD_COPY_RECT(rect->width, rect->height));
}
void draw_column(struct surface_data *surface_data,
- struct texture_data *texture_data, struct doomdev_column column,
+ struct texture_data *texture_data, struct doomdev_column *column,
struct colors_data *colors_data, struct colors_data *trans_data,
uint8_t flags, uint8_t trans_idx)
{
uint16_t y1, y2;
- y1 = min(column.y1, column.y2);
- y2 = max(column.y1, column.y2);
+ y1 = min(column->y1, column->y2);
+ y2 = max(column->y1, column->y2);
set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
set_surf_dims(surface_data->doom_data, surface_data->width, surface_data->height);
set_draw_params(surface_data->doom_data, flags);
- set_xy_a(surface_data->doom_data, column.x, y1);
- set_xy_b(surface_data->doom_data, column.x, y2);
+ set_xy_a(surface_data->doom_data, column->x, y1);
+ set_xy_b(surface_data->doom_data, column->x, y2);
if (!(flags & HARDDOOM_DRAW_PARAMS_FUZZ)) {
set_texture_pt(surface_data->doom_data,
texture_data->page_table_dev);
set_texture_dims(surface_data->doom_data,
texture_data->size, texture_data->height);
- set_ustart(surface_data->doom_data, column.ustart);
- set_ustep(surface_data->doom_data, column.ustep);
+ set_ustart(surface_data->doom_data, column->ustart);
+ set_ustep(surface_data->doom_data, column->ustep);
}
if (flags & HARDDOOM_DRAW_PARAMS_FUZZ ||
flags & HARDDOOM_DRAW_PARAMS_COLORMAP) {
set_colormap(surface_data->doom_data, colors_data->colors_dev +
- HARDDOOM_COLORMAP_SIZE * column.colormap_idx);
+ HARDDOOM_COLORMAP_SIZE * column->colormap_idx);
}
if (flags & HARDDOOM_DRAW_PARAMS_TRANSLATE) {
@@ -264,27 +264,27 @@ void draw_column(struct surface_data *surface_data,
}
send_command(surface_data->doom_data,
- HARDDOOM_CMD_DRAW_COLUMN(column.texture_offset));
+ HARDDOOM_CMD_DRAW_COLUMN(column->texture_offset));
}
void draw_span(struct surface_data *surface_data, struct flat_data *flat_data,
- struct doomdev_span span)
+ struct doomdev_span *span)
{
uint16_t x1, x2;
- x1 = min(span.x1, span.x2);
- x2 = max(span.x1, span.x2);
+ x1 = min(span->x1, span->x2);
+ x2 = max(span->x1, span->x2);
set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
set_surf_dims(surface_data->doom_data, surface_data->width,
surface_data->height);
set_flat(surface_data->doom_data, flat_data->flat_dev);
- set_xy_a(surface_data->doom_data, x1, span.y);
- set_xy_b(surface_data->doom_data, x2, span.y);
- set_ustart(surface_data->doom_data, span.ustart);
- set_ustep(surface_data->doom_data, span.ustep);
- set_vstart(surface_data->doom_data, span.vstart);
- set_vstep(surface_data->doom_data, span.vstep);
+ set_xy_a(surface_data->doom_data, x1, span->y);
+ set_xy_b(surface_data->doom_data, x2, span->y);
+ set_ustart(surface_data->doom_data, span->ustart);
+ set_ustep(surface_data->doom_data, span->ustep);
+ set_vstart(surface_data->doom_data, span->vstart);
+ set_vstep(surface_data->doom_data, span->vstep);
set_draw_params(surface_data->doom_data, 0);
send_command(surface_data->doom_data, HARDDOOM_CMD_DRAW_SPAN);
diff --git a/harddoomdev.h b/harddoomdev.h
index 90d2b51..d37dd59 100644
--- a/harddoomdev.h
+++ b/harddoomdev.h
@@ -15,16 +15,16 @@ void deactivate_intr(void __iomem *iomem, uint32_t intr);
void disable_intr(void __iomem *iomem, uint32_t intr);
void ping_sync(struct doom_data *doom_data);
-void draw_line(struct surface_data *surface_data, struct doomdev_line line);
-void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect rect);
+void draw_line(struct surface_data *surface_data, struct doomdev_line *line);
+void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect *rect);
void copy_rect(struct surface_data *dst_data, struct surface_data *src_data,
- struct doomdev_copy_rect rect);
+ struct doomdev_copy_rect *rect);
void draw_column(struct surface_data *surface_data,
- struct texture_data *texture_data, struct doomdev_column column,
+ struct texture_data *texture_data, struct doomdev_column *column,
struct colors_data *colors_data, struct colors_data *trans_data,
uint8_t flags, uint8_t trans_idx);
void draw_span(struct surface_data *surface_data, struct flat_data *flat_data,
- struct doomdev_span span);
+ struct doomdev_span *span);
void draw_background(struct surface_data *surface_data,
struct flat_data *flat_data);
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(&param, (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(&param, (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(&param, (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(&param, (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(&param, (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(&param, (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;
}