The attached patch fixes an uninitialized read from memory in `union_memsize`.
The summary of how the bug happens is: 1. union_memsize gets called with a pointer to uninitialized `dummy`. ``` static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *tfsoff) { [...] unsigned int dummy; [...] size = union_memsize(fields, &dummy); ``` 2. `union_memsize` reads `pmaxa` (which points to dummy) to set the initial value of align. ``` static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa) { unsigned int size, maxs = 0; unsigned int align = *pmaxa; const var_t *v; if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) { /* we could have an empty default field with NULL type */ if (v->declspec.type) { size = type_memsize_and_alignment(v->declspec.type, &align); if (maxs < size) maxs = size; if (*pmaxa < align) *pmaxa = align; } } ``` The rest of the code in `type_memsize_and_alignment` works with that unitialized alignment value. If the uninitialized memory happens to represent a larger uint than the actual max size of the union, then that value is printed in the result. Thanks! - Raphael Isemann
diff --git a/mingw-w64-tools/widl/src/typegen.c b/mingw-w64-tools/widl/src/typegen.c index b2d9ab5d1..eb0fa5e06 100644 --- a/mingw-w64-tools/widl/src/typegen.c +++ b/mingw-w64-tools/widl/src/typegen.c @@ -3310,41 +3310,41 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff) short reloff = t->typestring_offset - *tfsoff; print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %d (%d) */\n", reloff, reloff, t->typestring_offset); } else error("write_branch_type: type unimplemented %d\n", type_get_type(t)); } *tfsoff += 2; } static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs, type_t *type, unsigned int *tfsoff) { unsigned int start_offset; unsigned int size; var_list_t *fields; unsigned int nbranch = 0; type_t *deftype = NULL; short nodeftype = 0xffff; - unsigned int dummy; + unsigned int dummy = 0; var_t *f; if (processed(type) && (type_get_type(type) == TYPE_ENCAPSULATED_UNION || !is_attr(type->attrs, ATTR_SWITCHTYPE))) return type->typestring_offset; guard_rec(type); fields = type_union_get_cases(type); size = union_memsize(fields, &dummy); if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry) { expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); if (cases) nbranch += list_count(cases); if (f->declspec.type) write_embedded_types(file, f->attrs, f->declspec.type, f->name, TRUE, tfsoff); }
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public