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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public