diff options
author | Dave Airlie <airlied@redhat.com> | 2015-01-15 13:32:42 +1300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-01-21 13:38:32 +1300 |
commit | 06a4e627c85d212be8132dc95cd1c173e4200a44 (patch) | |
tree | 0e2dc97d02ce750b5b1aab187831540d3cfa69b0 | |
parent | 83790434e436486fa989a4a5c65164f76619cab0 (diff) |
renderer: report a buffer error if the guest tries to send illegal cmds
-rw-r--r-- | src/gallium/renderer/virgl_hw.h | 1 | ||||
-rw-r--r-- | src/gallium/renderer/vrend_decode.c | 22 | ||||
-rw-r--r-- | src/gallium/renderer/vrend_renderer.c | 5 | ||||
-rw-r--r-- | src/gallium/renderer/vrend_renderer.h | 1 |
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, |