On current master, when 'upcall_receive()' returns error, the
ofpbuf 'upcall->put_actions' is uninitialized.  In some usecase,
the failure of 'upcall_receive()' will cause uninitialize of
'upcall->put_actions' and free of uninitialized pointer.

This commit fixes the issue by making the caller not conduct
the uninitialize of the 'upcall' when there is error.

Found by inspection.

Signed-off-by: Alex Wang <al...@nicira.com>

---
PATCH -> V2:
1. make the caller just return the error.
2. fix the comment to warn the user.
---
 ofproto/ofproto-dpif-upcall.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index cce89dd..8e890f8 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -818,9 +818,10 @@ compose_slow_path(struct udpif *udpif, struct xlate_out 
*xout,
                              buf);
 }
 
-/* The upcall must be destroyed with upcall_uninit() before quiescing,
- * as the referred objects are guaranteed to exist only until the calling
- * thread quiesces. */
+/* If there is no error, the upcall must be destroyed with upcall_uninit()
+ * before quiescing, as the referred objects are guaranteed to exist only
+ * until the calling thread quiesces.  Otherwise, do not call upcall_uninit()
+ * since the 'upcall->put_actions' remains uninitialized. */
 static int
 upcall_receive(struct upcall *upcall, const struct dpif_backer *backer,
                const struct ofpbuf *packet, enum dpif_upcall_type type,
@@ -944,7 +945,7 @@ upcall_cb(const struct ofpbuf *packet, const struct flow 
*flow,
     error = upcall_receive(&upcall, udpif->backer, packet, type, userdata,
                            flow);
     if (error) {
-        goto out;
+        return error;
     }
 
     error = process_upcall(udpif, &upcall, actions);
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to