[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 14/88] qapi: add visit_start_union and visit_end_uni
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 14/88] qapi: add visit_start_union and visit_end_union |
Date: |
Thu, 8 Jan 2015 11:33:18 -0600 |
In some cases an input visitor might bail out on filling out a
struct for various reasons, such as missing fields when running
in strict mode. In the case of a QAPI Union type, this may lead
to cases where the .kind field which encodes the union type
is uninitialized. Subsequently, other visitors, such as the
dealloc visitor, may use this .kind value as if it were
initialized, leading to assumptions about the union type which
in this case may lead to segfaults. For example, freeing an
integer value.
However, we can generally rely on the fact that the always-present
.data void * field that we generate for these union types will
always be NULL in cases where .kind is uninitialized (at least,
there shouldn't be a reason where we'd do this purposefully).
So pass this information on to Visitor implementation via these
optional start_union/end_union interfaces so this information
can be used to guard against the situation above. We will make
use of this information in a subsequent patch for the dealloc
visitor.
Cc: address@hidden
Reported-by: Fam Zheng <address@hidden>
Suggested-by: Paolo Bonzini <address@hidden>
Reviewed-by: Paolo Bonzini <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
Signed-off-by: Luiz Capitulino <address@hidden>
(cherry picked from commit cee2dedb85b97e4976c83bea84064c3921b8b7ac)
Signed-off-by: Michael Roth <address@hidden>
---
include/qapi/visitor-impl.h | 2 ++
include/qapi/visitor.h | 2 ++
qapi/qapi-visit-core.c | 15 +++++++++++++++
scripts/qapi-visit.py | 6 ++++++
4 files changed, 25 insertions(+)
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index ecc0183..09bb0fd 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -55,6 +55,8 @@ struct Visitor
void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error
**errp);
/* visit_type_size() falls back to (*type_uint64)() if type_size is unset
*/
void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error
**errp);
+ bool (*start_union)(Visitor *v, bool data_present, Error **errp);
+ void (*end_union)(Visitor *v, bool data_present, Error **errp);
};
void input_type_enum(Visitor *v, int *obj, const char *strings[],
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 4a0178f..5934f59 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -58,5 +58,7 @@ void visit_type_size(Visitor *v, uint64_t *obj, const char
*name, Error **errp);
void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
void visit_type_number(Visitor *v, double *obj, const char *name, Error
**errp);
+bool visit_start_union(Visitor *v, bool data_present, Error **errp);
+void visit_end_union(Visitor *v, bool data_present, Error **errp);
#endif
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 55f8d40..b66b93a 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -58,6 +58,21 @@ void visit_end_list(Visitor *v, Error **errp)
v->end_list(v, errp);
}
+bool visit_start_union(Visitor *v, bool data_present, Error **errp)
+{
+ if (v->start_union) {
+ return v->start_union(v, data_present, errp);
+ }
+ return true;
+}
+
+void visit_end_union(Visitor *v, bool data_present, Error **errp)
+{
+ if (v->end_union) {
+ v->end_union(v, data_present, errp);
+ }
+}
+
void visit_optional(Visitor *v, bool *present, const char *name,
Error **errp)
{
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index c129697..cfce31b 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -357,6 +357,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const
char *name, Error **e
if (err) {
goto out_obj;
}
+ if (!visit_start_union(m, !!(*obj)->data, &err) || err) {
+ goto out_obj;
+ }
switch ((*obj)->kind) {
''',
disc_type = disc_type,
@@ -385,6 +388,9 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const
char *name, Error **e
out_obj:
error_propagate(errp, err);
err = NULL;
+ visit_end_union(m, !!(*obj)->data, &err);
+ error_propagate(errp, err);
+ err = NULL;
}
visit_end_struct(m, &err);
out:
--
1.9.1
- [Qemu-devel] [PATCH 01/88] qdev: Use NULL instead of local_err for qbus_child unrealize, (continued)
- [Qemu-devel] [PATCH 01/88] qdev: Use NULL instead of local_err for qbus_child unrealize, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 03/88] exec: file_ram_alloc(): print error when prealloc fails, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 10/88] virtio-pci: enable bus master for old guests, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 05/88] Introduce cpu_clean_all_dirty, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 08/88] kvmclock: Add comment explaining why we need cpu_clean_all_dirty(), Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 09/88] pci: Use bus master address space for delivering MSI/MSI-X messages, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 07/88] kvmclock: Ensure time in migration never goes backward, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 06/88] kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 12/88] hw/arm/virt: fix pl011 and pl031 irq flags, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 13/88] gdbstub: init mon_chr through qemu_chr_alloc, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 14/88] qapi: add visit_start_union and visit_end_union,
Michael Roth <=
- [Qemu-devel] [PATCH 11/88] spapr_pci: map the MSI window in each PHB, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 15/88] qapi: dealloc visitor, implement visit_start_union, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 16/88] tests: add QMP input visitor test for unions with no discriminator, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 17/88] qemu-iotests: Test missing "driver" key for blockdev-add, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 18/88] monitor: Reset HMP mon->rs in CHR_EVENT_OPEN, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 20/88] vhost-user: fix VIRTIO_NET_F_MRG_RXBUF negotiation, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 22/88] ivshmem: validate incoming_posn value from server, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 24/88] ivshmem: Fix fd leak on error, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 25/88] pc-dimm: Don't check dimm->node when there is non-NUMA config, Michael Roth, 2015/01/08
- [Qemu-devel] [PATCH 26/88] tests: avoid running duplicate qom-tests, Michael Roth, 2015/01/08