Silences a very common warning.
-- v3: vkd3d-shader/dxbc: Validate and skip the signature section header size. vkd3d-shader/dxbc: Emit a shader error for an invalid signature data size. vkd3d-shader/dxbc: Pass a message context to for_each_dxbc_section().
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxbc.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index d8eef8a5..b01e30e5 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -1867,7 +1867,8 @@ void vkd3d_shader_free_dxbc(struct vkd3d_shader_dxbc_desc *dxbc)
static int for_each_dxbc_section(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context, const char *source_name, - int (*section_handler)(const struct vkd3d_shader_dxbc_section_desc *section, void *ctx), void *ctx) + int (*section_handler)(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *ctx), void *ctx) { struct vkd3d_shader_dxbc_desc desc; unsigned int i; @@ -1878,7 +1879,7 @@ static int for_each_dxbc_section(const struct vkd3d_shader_code *dxbc,
for (i = 0; i < desc.section_count; ++i) { - if ((ret = section_handler(&desc.sections[i], ctx)) < 0) + if ((ret = section_handler(&desc.sections[i], message_context, ctx)) < 0) break; }
@@ -1916,7 +1917,7 @@ int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxbc, }
static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *section, - struct vkd3d_shader_signature *s) + struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *s) { bool has_stream_index, has_min_precision; struct vkd3d_shader_signature_element *e; @@ -2002,7 +2003,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s return VKD3D_OK; }
-static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section, void *ctx) +static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *ctx) { struct vkd3d_shader_signature *is = ctx;
@@ -2014,7 +2016,7 @@ static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section, vo FIXME("Multiple input signatures.\n"); vkd3d_shader_free_shader_signature(is); } - return shader_parse_signature(section, is); + return shader_parse_signature(section, message_context, is); }
int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, @@ -2029,7 +2031,8 @@ int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, return ret; }
-static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, void *context) +static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *context) { struct vkd3d_shader_desc *desc = context; int ret; @@ -2043,7 +2046,7 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, vo FIXME("Multiple input signatures.\n"); break; } - if ((ret = shader_parse_signature(section, &desc->input_signature)) < 0) + if ((ret = shader_parse_signature(section, message_context, &desc->input_signature)) < 0) return ret; break;
@@ -2055,7 +2058,7 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, vo FIXME("Multiple output signatures.\n"); break; } - if ((ret = shader_parse_signature(section, &desc->output_signature)) < 0) + if ((ret = shader_parse_signature(section, message_context, &desc->output_signature)) < 0) return ret; break;
@@ -2066,7 +2069,7 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, vo FIXME("Multiple patch constant signatures.\n"); break; } - if ((ret = shader_parse_signature(section, &desc->patch_constant_signature)) < 0) + if ((ret = shader_parse_signature(section, message_context, &desc->patch_constant_signature)) < 0) return ret; break;
@@ -2618,7 +2621,8 @@ static int shader_parse_root_signature(const struct vkd3d_shader_code *data, return VKD3D_OK; }
-static int rts0_handler(const struct vkd3d_shader_dxbc_section_desc *section, void *context) +static int rts0_handler(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *context) { struct vkd3d_shader_versioned_root_signature_desc *desc = context;
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxbc.c | 2 ++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 3 insertions(+)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index b01e30e5..008be3c8 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -1929,6 +1929,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s if (!require_space(0, 2, sizeof(uint32_t), section->data.size)) { WARN("Invalid data size %#zx.\n", section->data.size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, + "Section size %zu is smaller than the minimum signature header size.\n", section->data.size); return VKD3D_ERROR_INVALID_ARGUMENT; }
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 78a48e55..64a53803 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -69,6 +69,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET = 5, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6, VKD3D_SHADER_ERROR_DXBC_OUT_OF_MEMORY = 7, + VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE = 8,
VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_RANGE = 1001,
From: Conor McCarthy cmccarthy@codeweavers.com
Silences a very common warning. --- libs/vkd3d-shader/dxbc.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 008be3c8..c7a52195 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -1709,6 +1709,9 @@ static void skip_dword_unknown(const char **ptr, unsigned int count) unsigned int i; uint32_t d;
+ if (!count) + return; + WARN("Skipping %u unknown DWORDs:\n", count); for (i = 0; i < count; ++i) { @@ -1922,9 +1925,9 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s bool has_stream_index, has_min_precision; struct vkd3d_shader_signature_element *e; const char *data = section->data.code; + uint32_t count, header_size; const char *ptr = data; unsigned int i; - uint32_t count;
if (!require_space(0, 2, sizeof(uint32_t), section->data.size)) { @@ -1937,7 +1940,17 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s read_dword(&ptr, &count); TRACE("%u elements.\n", count);
- skip_dword_unknown(&ptr, 1); /* It seems to always be 0x00000008. */ + read_dword(&ptr, &header_size); + i = header_size / sizeof(uint32_t); + if (align(header_size, sizeof(uint32_t)) != header_size || i < 2 + || !require_space(2, i - 2, sizeof(uint32_t), section->data.size)) + { + WARN("Invalid header size %#x.\n", header_size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, + "Signature header size %#x is invalid.\n", header_size); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + skip_dword_unknown(&ptr, i - 2);
if (!require_space(ptr - data, count, 6 * sizeof(uint32_t), section->data.size)) {
This merge request was approved by Henri Verbeet.