From: Markus Armbruster <armbru@redhat.com>
To: Eric Blake <eblake@redhat.com>
Cc: qemu-devel@nongnu.org, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH v10 12/13] qapi: Delete unused visit_start_union()
Date: Thu, 18 Feb 2016 09:24:18 +0100 [thread overview]
Message-ID: <87si0ql93h.fsf@blackfin.pond.sub.org> (raw)
In-Reply-To: <56C4E3EC.7040800@redhat.com> (Eric Blake's message of "Wed, 17 Feb 2016 14:19:40 -0700")
Eric Blake <eblake@redhat.com> writes:
> On 02/17/2016 11:08 AM, Markus Armbruster wrote:
>> Eric Blake <eblake@redhat.com> writes:
>>
>>> Commit cee2dedb noticed that if you have a partial flat union
>>> (such as if an input parse failed due to a missing
>>> discriminator), calling the dealloc visitor could result in
>>> trying to dereference a NULL pointer if we attempted to visit
>>> an object branch without an earlier successful call to
>>> visit_start_implicit_struct() allocating the pointer for that
>>> branch. But the "fix" it implemented requires the use of a
>>> '.data' member in the union, which may or may not be the same
>>> size as other branches of the union (consider a 32-bit platform
>>> where one of the branches is an int64), which feels fairly dirty.
>>
>> Well, until the previous commit, it was the same, wasn't it? All
>> pointers.
>
> For simple unions, you could have (well, still can have, until my later
> patch gets rid of the simple_union_type() magic):
>
> struct SU {
> SUKind type;
> union {
> void *data;
> int8_t byte;
> } u;
> };
Begs the question why that works :)
> But you're right - for flat unions, ALL branches were represented as
> pointers (until this series unboxed them).
>
>>
>>> Plus, as mentioned in that commit, it only works if you can
>>> assume that '.data' would be zero-initialized even if '.kind' was
>>> uninitialized, which is rather poor logic: our usage of
>>> visit_start_struct() happens to zero-initialize both fields,
>>> which means '.kind' is never truly uninitialized - but if we
>>> changed visit_start_struct() to use g_new() instead of g_new0(),
>>> then '.data' would not be any more reliable as a condition on
>>> whether to visit the branch matching '.kind', regardless of
>>> whether '.kind' was 0).
>>>
>>> Menawhile, now that we have just inlined the fields of all flat
>
> Meanwhile,
>
>>> unions, there is no longer the possibility of a null pointer to
>>> dereference in the first place. Where the branch structure used
>>> to be separately allocated by visit_start_implicit_struct(), it
>>> is now just pointing to a subset of the memory already
>>> zero-allocated by visit_start_struct().
>
> I guess I may try and reword this slightly, and point to the fact that
> the NULL dereference was due to calling visit_start_implicit_FOO() (only
> done for flat unions; for simple unions the branches call
> visit_type_FOO(), and that call safely handled NULL);
That's why it works?
> because we were
> using visit_start/end_implicit_struct() for its allocation effects. But
> the net result is the same - now that we no longer call
> visit_start_implicit_struct() for a union visit, the dealloc visitor no
> longer has to worry about a NULL dereference on a partially constructed
> object, so we no longer need to probe if the union contains any data.
>
>>> +++ b/scripts/qapi-visit.py
>>> @@ -246,9 +246,6 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
>>> if variants:
>>> ret += gen_err_check(label='out_obj')
>>> ret += mcgen('''
>>> - if (!visit_start_union(v, !!(*obj)->u.data, &err) || err) {
>>> - goto out_obj;
>>> - }
>>
>> I'm afraid the previous commit broke this for flat unions.
>>
>> Before the previous commit, all members of (*obj)->u were pointers to
>> the struct holding the variant members both for flat and simple unions.
>> !!(*obj)->u.data tests whether the struct holding the variant members
>> has been allocated. This relies on uniform pointer format.
>>
>> The dealloc visitor uses the "has been allocated" bit to suppress
>> visiting the struct when it hasn't been allocated.
>>
>> The previous commit unboxes the struct for flat unions. Now ->u.data
>> reinterprets the first few bytes of that struct as pointer. If you're
>> "lucky", they're not all zero, and the struct gets visited.
>
> You're right - and I bet I could come up with a case where valgrind
> could call me on it.
>
>>
>> Obvious fix: squash this hunk into the previous commit, then let this
>> commit drop the code that's no longer used.
>
> Yep, for bisectability, I think that's what I'll end up doing.
>
>>
>> However, simple unions are still boxed. Why can't their pointer be null
>> in the dealloc visitor?
>
> Simple unions still go through visit_type_FOO(), and _that_ function
> properly checks for NULL. It was only visit_type_implicit_FOO() that
> blindly dereferenced things. In fact, in the earlier incantation of
> this patch, my fix was to teach visit_type_implicit_FOO() how to check
> for NULL:
> https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg05442.html
>
> But now that visit_type_implicit_FOO() is gone, my earlier incantation
> got reduced in size. I guess it's all in how I document the commit message.
Give it a try :)
next prev parent reply other threads:[~2016-02-18 8:24 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-16 0:20 [Qemu-devel] [PATCH v10 00/13] prune some QAPI visitor cruft (was qapi cleanups subset E) Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 01/13] qapi: Simplify excess input reporting in input visitors Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 02/13] qapi: Forbid empty unions and useless alternates Eric Blake
2016-02-16 16:08 ` Markus Armbruster
2016-02-16 23:18 ` Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 03/13] qapi: Reposition error checks in gen_visit_fields() Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 04/13] qapi: Drop pointless gotos in generated code Eric Blake
2016-02-16 16:27 ` Markus Armbruster
2016-02-16 17:14 ` Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 05/13] qapi-visit: Simplify how we visit common union members Eric Blake
2016-02-16 16:31 ` Markus Armbruster
2016-02-16 17:17 ` Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 06/13] qapi-visit: Unify struct and union visit Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 07/13] qapi-visit: Less indirection in visit_type_Foo_fields() Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 08/13] qapi: Adjust layout of FooList types Eric Blake
2016-02-16 16:55 ` Markus Armbruster
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 09/13] qapi: Emit structs used as variants in topological order Eric Blake
2016-02-16 17:03 ` Markus Armbruster
2016-02-16 17:32 ` Eric Blake
2016-02-16 21:00 ` Markus Armbruster
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 10/13] qapi: Don't box struct branch of alternate Eric Blake
2016-02-16 19:07 ` Markus Armbruster
2016-02-16 19:53 ` Eric Blake
2016-02-17 14:40 ` Markus Armbruster
2016-02-17 20:34 ` Eric Blake
2016-02-18 8:21 ` Markus Armbruster
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 11/13] qapi: Don't box branches of flat unions Eric Blake
2016-02-17 17:44 ` Markus Armbruster
2016-02-17 20:53 ` Eric Blake
2016-02-18 8:51 ` Markus Armbruster
2016-02-18 16:51 ` Eric Blake
2016-02-18 17:11 ` Markus Armbruster
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 12/13] qapi: Delete unused visit_start_union() Eric Blake
2016-02-17 18:08 ` Markus Armbruster
2016-02-17 21:19 ` Eric Blake
2016-02-18 8:24 ` Markus Armbruster [this message]
2016-02-18 16:47 ` Eric Blake
2016-02-16 0:20 ` [Qemu-devel] [PATCH v10 13/13] qapi: Change visit_start_implicit_struct to visit_start_alternate Eric Blake
2016-02-17 18:13 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87si0ql93h.fsf@blackfin.pond.sub.org \
--to=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.