vrend: Check GL errors

There are many combinations of invalid arguments for OpenGL functions
and it is impractical to cover all of them.

Even if nothing is wrong with the user, GL_CONTEXT_LOST and
GL_OUT_OF_MEMORY can also occur in many GL functions due to hardware
problems. They can leave the context in an invalid state which can
result in a reliability or security issue.

Check GL errors after an operation completes and prevent from using the
GL context after a GL error occurred.

spec@!opengl 1.5@draw-vertices, spec@!opengl 1.5@draw-vertices-user,
and spec@!opengl 2.0@gl-2.0-vertexattribpointer are marked as crash in
.gitlab-ci/expectations/host/piglit-virgl-gles-fails.txt because they
require GL_DOUBLE specification for glVertexAttribPointer, which is
not supported by OpenGL ES. Avoiding the crashes requires capability
checks on the guest, which this change does not implement.

Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
macos/master
Akihiko Odaki 3 years ago
parent edbc0c3569
commit 326953a662
  1. 6
      .gitlab-ci/expectations/host/piglit-virgl-gles-fails.txt
  2. 1
      .gitlab-ci/expectations/virt/piglit-virgl-gles-fails.txt
  3. 5
      src/vrend_decode.c
  4. 21
      src/vrend_renderer.c
  5. 2
      src/vrend_renderer.h
  6. 2
      tests/test_virgl_transfer.c

@ -3391,12 +3391,12 @@ spec@!opengl 1.4@gl-1.4-tex1d-2dborder,Fail
spec@!opengl 1.4@tex-miplevel-selection-lod-bias,Fail
spec@!opengl 1.5@depth-tex-compare,Fail
spec@!opengl 1.5@draw-elements-user,Fail
spec@!opengl 1.5@draw-vertices,Fail
spec@!opengl 1.5@draw-vertices-user,Fail
spec@!opengl 1.5@draw-vertices,Crash
spec@!opengl 1.5@draw-vertices-user,Crash
spec@!opengl 2.0@gl-2.0-edgeflag,Fail
spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail
spec@!opengl 2.0@gl-2.0-large-point-fs,Fail
spec@!opengl 2.0@gl-2.0-vertexattribpointer,Fail
spec@!opengl 2.0@gl-2.0-vertexattribpointer,Crash
spec@!opengl 2.0@occlusion-query-discard,Fail
spec@!opengl 2.0@vertex-program-two-side enabled back2,Fail
spec@!opengl 2.0@vertex-program-two-side enabled back2@vs and fs,Fail

@ -3473,7 +3473,6 @@ spec@!opengl 1.5@draw-vertices-user,Fail
spec@!opengl 2.0@gl-2.0-edgeflag,Fail
spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail
spec@!opengl 2.0@gl-2.0-large-point-fs,Fail
spec@!opengl 2.0@gl-2.0-vertexattribpointer,Fail
spec@!opengl 2.0@occlusion-query-discard,Fail
spec@!opengl 2.0@vertex-program-two-side enabled back2,Fail
spec@!opengl 2.0@vertex-program-two-side enabled back2@vs and fs,Fail

@ -1570,8 +1570,9 @@ static int vrend_decode_ctx_transfer_3d(struct virgl_context *ctx,
{
TRACE_FUNC();
struct vrend_decode_ctx *dctx = (struct vrend_decode_ctx *)ctx;
return vrend_renderer_transfer_iov(dctx->grctx, res->res_id, info,
int ret = vrend_renderer_transfer_iov(dctx->grctx, res->res_id, info,
transfer_mode);
return vrend_check_no_error(dctx->grctx) || ret ? ret : EINVAL;
}
static int vrend_decode_ctx_get_blob(struct virgl_context *ctx,
@ -1734,6 +1735,8 @@ static int vrend_decode_ctx_submit_cmd(struct virgl_context *ctx,
TRACE_SCOPE_SLOW(vrend_get_comand_name(cmd));
ret = decode_table[cmd](gdctx->grctx, buf, len);
if (!vrend_check_no_error(gdctx->grctx) && !ret)
ret = EINVAL;
if (ret) {
vrend_printf("context %d failed to dispatch %s: %d\n",
gdctx->base.ctx_id, vrend_get_comand_name(cmd), ret);

@ -6452,6 +6452,22 @@ static uint64_t vrend_pipe_resource_get_size(struct pipe_resource *pres,
return res->size;
}
bool vrend_check_no_error(struct vrend_context *ctx)
{
GLenum err;
err = glGetError();
if (err == GL_NO_ERROR)
return true;
while (err != GL_NO_ERROR) {
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_UNKNOWN, err);
err = glGetError();
}
return false;
}
const struct virgl_resource_pipe_callbacks *
vrend_renderer_get_pipe_callbacks(void)
{
@ -6611,6 +6627,11 @@ int vrend_renderer_init(const struct vrend_if_cbs *cbs, uint32_t flags)
vrend_state.use_egl_fence = virgl_egl_supports_fences(egl);
#endif
if (!vrend_check_no_error(vrend_state.ctx0)) {
vrend_renderer_fini();
return EINVAL;
}
return 0;
}

@ -128,6 +128,8 @@ struct vrend_if_cbs {
#define VREND_USE_EXTERNAL_BLOB (1 << 1)
#define VREND_USE_ASYNC_FENCE_CB (1 << 2)
bool vrend_check_no_error(struct vrend_context *ctx);
const struct virgl_resource_pipe_callbacks *
vrend_renderer_get_pipe_callbacks(void);

@ -879,7 +879,7 @@ START_TEST(virgl_test_copy_transfer_to_staging_without_iov_fails)
virgl_encoder_copy_transfer(&ctx, &dst_res, 0, 0, &box, &src_res, 0, synchronized);
ret = virgl_renderer_submit_cmd(ctx.cbuf->buf, ctx.ctx_id, ctx.cbuf->cdw);
ck_assert_int_eq(ret, 0);
ck_assert_int_eq(ret, EINVAL);
virgl_renderer_ctx_detach_resource(ctx.ctx_id, src_res.handle);
virgl_renderer_ctx_detach_resource(ctx.ctx_id, dst_res.handle);

Loading…
Cancel
Save