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

Reply via email to