summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-01-15 13:32:42 +1300
committerDave Airlie <airlied@redhat.com>2015-01-21 13:38:32 +1300
commit06a4e627c85d212be8132dc95cd1c173e4200a44 (patch)
tree0e2dc97d02ce750b5b1aab187831540d3cfa69b0
parent83790434e436486fa989a4a5c65164f76619cab0 (diff)
renderer: report a buffer error if the guest tries to send illegal cmds
-rw-r--r--src/gallium/renderer/virgl_hw.h1
-rw-r--r--src/gallium/renderer/vrend_decode.c22
-rw-r--r--src/gallium/renderer/vrend_renderer.c5
-rw-r--r--src/gallium/renderer/vrend_renderer.h1
4 files changed, 21 insertions, 8 deletions
diff --git a/src/gallium/renderer/virgl_hw.h b/src/gallium/renderer/virgl_hw.h
index ca2be92ae19..b2d52700e34 100644
--- a/src/gallium/renderer/virgl_hw.h
+++ b/src/gallium/renderer/virgl_hw.h
@@ -241,6 +241,7 @@ enum virgl_ctx_errors {
VIRGL_ERROR_CTX_ILLEGAL_RESOURCE,
VIRGL_ERROR_CTX_ILLEGAL_SURFACE,
VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT,
+ VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER,
};
diff --git a/src/gallium/renderer/vrend_decode.c b/src/gallium/renderer/vrend_decode.c
index 672d3b1c06c..10eda8cfdbf 100644
--- a/src/gallium/renderer/vrend_decode.c
+++ b/src/gallium/renderer/vrend_decode.c
@@ -868,8 +868,14 @@ void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
while (gdctx->ds->buf_offset < gdctx->ds->buf_total) {
uint32_t header = gdctx->ds->buf[gdctx->ds->buf_offset];
+ uint32_t len = header >> 16;
-// fprintf(stderr,"[%d] cmd is %d (obj %d) len %d\n", gdctx->ds->buf_offset, header & 0xff, (header >> 8 & 0xff), (header >> 16));
+ /* check if the guest is doing something bad */
+ if (gdctx->ds->buf_offset + len + 1 > gdctx->ds->buf_total) {
+ vrend_report_buffer_error(gdctx->grctx);
+ break;
+ }
+// fprintf(stderr,"[%d] cmd is %d (obj %d) len %d\n", gdctx->ds->buf_offset, header & 0xff, (header >> 8 & 0xff), (len));
switch (header & 0xff) {
case VIRGL_CCMD_CREATE_OBJECT:
@@ -891,22 +897,22 @@ void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
vrend_decode_set_framebuffer_state(gdctx);
break;
case VIRGL_CCMD_SET_VERTEX_BUFFERS:
- vrend_decode_set_vertex_buffers(gdctx, header >> 16);
+ vrend_decode_set_vertex_buffers(gdctx, len);
break;
case VIRGL_CCMD_RESOURCE_INLINE_WRITE:
- vrend_decode_resource_inline_write(gdctx, header >> 16);
+ vrend_decode_resource_inline_write(gdctx, len);
break;
case VIRGL_CCMD_SET_VIEWPORT_STATE:
vrend_decode_set_viewport_state(gdctx);
break;
case VIRGL_CCMD_SET_SAMPLER_VIEWS:
- vrend_decode_set_sampler_views(gdctx, header >> 16);
+ vrend_decode_set_sampler_views(gdctx, len);
break;
case VIRGL_CCMD_SET_INDEX_BUFFER:
vrend_decode_set_index_buffer(gdctx);
break;
case VIRGL_CCMD_SET_CONSTANT_BUFFER:
- vrend_decode_set_constant_buffer(gdctx, header >> 16);
+ vrend_decode_set_constant_buffer(gdctx, len);
break;
case VIRGL_CCMD_SET_STENCIL_REF:
vrend_decode_set_stencil_ref(gdctx);
@@ -924,7 +930,7 @@ void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
vrend_decode_resource_copy_region(gdctx);
break;
case VIRGL_CCMD_BIND_SAMPLER_STATES:
- vrend_decode_bind_sampler_states(gdctx, header >> 16);
+ vrend_decode_bind_sampler_states(gdctx, len);
break;
case VIRGL_CCMD_BEGIN_QUERY:
vrend_decode_begin_query(gdctx);
@@ -945,7 +951,7 @@ void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
vrend_decode_set_sample_mask(gdctx);
break;
case VIRGL_CCMD_SET_STREAMOUT_TARGETS:
- vrend_decode_set_streamout_targets(gdctx, header >> 16);
+ vrend_decode_set_streamout_targets(gdctx, len);
break;
case VIRGL_CCMD_SET_RENDER_CONDITION:
vrend_decode_set_render_condition(gdctx);
@@ -963,7 +969,7 @@ void vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw)
vrend_decode_destroy_sub_ctx(gdctx);
break;
}
- gdctx->ds->buf_offset += (header >> 16) + 1;
+ gdctx->ds->buf_offset += (len) + 1;
}
diff --git a/src/gallium/renderer/vrend_renderer.c b/src/gallium/renderer/vrend_renderer.c
index 7bb578cb350..d0095ebfeae 100644
--- a/src/gallium/renderer/vrend_renderer.c
+++ b/src/gallium/renderer/vrend_renderer.c
@@ -407,6 +407,11 @@ static void __report_context_error(const char *fname, struct vrend_context *ctx,
}
#define report_context_error(ctx, error, value) __report_context_error(__func__, ctx, error, value)
+void vrend_report_buffer_error(struct vrend_context *ctx)
+{
+ report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, 0);
+}
+
#define CORE_PROFILE_WARN_NONE 0
#define CORE_PROFILE_WARN_STIPPLE 1
#define CORE_PROFILE_WARN_POLYGON_MODE 2
diff --git a/src/gallium/renderer/vrend_renderer.h b/src/gallium/renderer/vrend_renderer.h
index 379056b0fdb..38571c86f57 100644
--- a/src/gallium/renderer/vrend_renderer.h
+++ b/src/gallium/renderer/vrend_renderer.h
@@ -376,6 +376,7 @@ void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id);
void vrend_renderer_destroy_sub_ctx(struct vrend_context *ctx, int sub_ctx_id);
void vrend_renderer_set_sub_ctx(struct vrend_context *ctx, int sub_ctx_id);
+void vrend_report_buffer_error(struct vrend_context *ctx);
void vrend_fb_bind_texture(struct vrend_resource *res,
int idx,