Commit da546e0 (dpif: Allow execute to modify the packet.) uninitializes the "dpif_upcall.packet" of "struct upcall" when dpif_recv() returns error. The packet ofpbuf is likely uninitialized in this case, hence calling ofpbuf_uninit() on it will likely cause a SEGFAULT.
This commit fixes this bug by only uninitializing packet's ofpbuf on successfully received upcalls. A note warning about this is added on the comment of dpif_recv() in dpif-provider.h. Reported-by: Alex Wang <al...@nicira.com> Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- lib/dpif-provider.h | 4 +++- ofproto/ofproto-dpif-upcall.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index f279934..90a02b4 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -349,7 +349,9 @@ struct dpif_class { * The caller owns the data of 'upcall->packet' and may modify it. If * packet's headroom is exhausted as it is manipulated, 'upcall->packet' * will be reallocated. This requires the data of 'upcall->packet' to be - * released with ofpbuf_uninit() before 'upcall' is destroyed. + * released with ofpbuf_uninit() before 'upcall' is destroyed. However, + * when an error is returned, the 'upcall->packet' may be uninitialized + * and should not be released. * * This function must not block. If no upcall is pending when it is * called, it should return EAGAIN without blocking. */ diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 53a9e82..7c8e24e 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -533,7 +533,10 @@ recv_upcalls(struct udpif *udpif) error = dpif_recv(udpif->dpif, &upcall->dpif_upcall, &upcall->upcall_buf); if (error) { - upcall_destroy(upcall); + /* upcall_destroy() can only be called on successfully received + * upcalls. */ + ofpbuf_uninit(&upcall->upcall_buf); + free(upcall); break; } -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev