dp_packet_batch_add() may flush a full batch and free the packet.
In dp_packet_gso__(), the original packet was added to the batch
before all header and payload information was extracted, which could
lead to accessing a freed packet.

Move the header length and data length extraction before adding the
packet to the batch, and only add the original packet after all
modifications are complete.

This preserves the existing behavior while preventing a potential
use-after-free.

Signed-off-by: SeungJu Cheon <[email protected]>
---
 lib/dp-packet-gso.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/dp-packet-gso.c b/lib/dp-packet-gso.c
index bceb851fb..873568bac 100644
--- a/lib/dp-packet-gso.c
+++ b/lib/dp-packet-gso.c
@@ -194,6 +194,16 @@ dp_packet_gso__(struct dp_packet *p, struct 
dp_packet_batch **batches,
     udp_tnl = dp_packet_tunnel_vxlan(p) || dp_packet_tunnel_geneve(p);
     gre_tnl = dp_packet_tunnel_gre(p);
 
+    if (dp_packet_tunnel(p)) {
+        hdr_len = (char *) dp_packet_get_inner_tcp_payload(p)
+                  - (char *) dp_packet_eth(p);
+        data_len = dp_packet_get_inner_tcp_payload_length(p);
+    } else {
+        hdr_len = (char *) dp_packet_get_tcp_payload(p)
+                  - (char *) dp_packet_eth(p);
+        data_len = dp_packet_get_tcp_payload_length(p);
+    }
+
     /* Put back the first segment in the batch, it will be trimmed after
      * all segments have been copied. */
     if (dp_packet_batch_is_full(curr_batch)) {
@@ -205,16 +215,6 @@ dp_packet_gso__(struct dp_packet *p, struct 
dp_packet_batch **batches,
         goto out;
     }
 
-    if (dp_packet_tunnel(p)) {
-        hdr_len = (char *) dp_packet_get_inner_tcp_payload(p)
-                  - (char *) dp_packet_eth(p);
-        data_len = dp_packet_get_inner_tcp_payload_length(p);
-    } else {
-        hdr_len = (char *) dp_packet_get_tcp_payload(p)
-                  - (char *) dp_packet_eth(p);
-        data_len = dp_packet_get_tcp_payload_length(p);
-    }
-
     if (partial_seg) {
         if (dp_packet_gso_partial_nr_segs(p) != 1) {
             goto last_seg;
-- 
2.52.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to