File openvswitch-CVE-2025-0650.patch of Package openvswitch.37502

From 273dc3f6e7a8543f7c3b76bdb06fb34600e3ff61 Mon Sep 17 00:00:00 2001
From: Clemens Famulla-Conrad <cfamullaconrad@suse.de>
Date: Tue, 11 Feb 2025 15:40:25 +0100
Subject: [PATCH 1/1] bsc#1236353 (CVE-2025-0650) ovn: egress ACLs may be
 bypassed via specially crafted UDP packet
Reference: bsc#1236353
Upstream: 4140fead049ecef6a6b0f90e74f5de7d5a40fd5d

Backported upstream fix 4140fead0 without tests.

---

[PATCH 1/1] Skip only OVN DNS responder packets from OUT_ACL.

When OVN's DNS caching feature is enabled, due to the OpenFlow rules
that OVN installs in Open vSwitch, it is possible for an attacker to
craft a UDP packet that can bypass egress ACL rules configured on the
same switch that has DNS caching configured.

This patch fixes the issue by setting a register bit when OVN's DNS
responder replies to an incoming request. Then the flow that allows
egress ACL bypass only applies to packets that have this register bit
set. This gives the intended effect of allowing internally-generated DNS
responses to not be blocked by user-defined ACLs without potentially
compromising the security of the switch.

Signed-off-by: Numan Siddique <numans@ovn.org>
Signed-off-by: Mark Michelson <mmichels@redhat.com>
Acked-by: Dumitru Ceara <dceara@redhat.com>
---
 ovn/controller/pinctrl.c | 27 +++++++++++++++++++++++++++
 ovn/lib/logical-fields.c |  3 +++
 ovn/lib/logical-fields.h |  1 +
 ovn/northd/ovn-northd.c  |  3 ++-
 4 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c
index 4d995d5b0..faec8fb04 100644
--- a/ovn/controller/pinctrl.c
+++ b/ovn/controller/pinctrl.c
@@ -111,6 +111,8 @@ static void send_ipv6_ras(
     const struct hmap *local_datapaths);
 ;
 
+static void set_from_ctrl_flag_in_pkt_metadata(struct ofputil_packet_in *);
+
 COVERAGE_DEFINE(pinctrl_drop_put_mac_binding);
 COVERAGE_DEFINE(pinctrl_drop_buffered_packets_map);
 
@@ -1375,6 +1377,10 @@ exit:
         union mf_subvalue sv;
         sv.u8_val = success;
         mf_write_subfield(&dst, &sv, &pin->flow_metadata);
+
+        /* Indicate that this packet is from ovn-controller. */
+        set_from_ctrl_flag_in_pkt_metadata(pin);
+
     }
     queue_msg(ofputil_encode_resume(pin, continuation, proto));
     dp_packet_uninit(pkt_out_ptr);
@@ -2765,3 +2771,24 @@ exit:
     queue_msg(ofputil_encode_resume(pin, continuation, proto));
     dp_packet_uninit(pkt_out_ptr);
 }
+
+/* This function sets the register bit 'MLF_FROM_CTRL_BIT'
+ * in the register 'MFF_LOG_FLAGS' to indicate that this packet
+ * is generated/sent by ovn-controller.
+ * ovn-northd can add logical flows to match on "flags.from_ctrl".
+ */
+static void
+set_from_ctrl_flag_in_pkt_metadata(struct ofputil_packet_in *pin)
+{
+    const struct mf_field *f = mf_from_id(MFF_LOG_FLAGS);
+
+    struct mf_subfield dst = {
+        .field = f,
+        .ofs = MLF_FROM_CTRL_BIT,
+        .n_bits = 1,
+    };
+
+    union mf_subvalue sv;
+    sv.u8_val = 1;
+    mf_write_subfield(&dst, &sv, &pin->flow_metadata);
+}
diff --git a/ovn/lib/logical-fields.c b/ovn/lib/logical-fields.c
index a8b5e3c51..30eb40eb4 100644
--- a/ovn/lib/logical-fields.c
+++ b/ovn/lib/logical-fields.c
@@ -106,6 +106,9 @@ ovn_init_symtab(struct shash *symtab)
     expr_symtab_add_subfield(symtab, "flags.force_snat_for_lb", NULL,
                              flags_str);
 
+    snprintf(flags_str, sizeof flags_str, "flags[%d]", MLF_FROM_CTRL_BIT);
+    expr_symtab_add_subfield(symtab, "flags.from_ctrl", NULL, flags_str);
+
     /* Connection tracking state. */
     expr_symtab_add_field(symtab, "ct_mark", MFF_CT_MARK, NULL, false);
 
diff --git a/ovn/lib/logical-fields.h b/ovn/lib/logical-fields.h
index 95759a8bb..981d9863d 100644
--- a/ovn/lib/logical-fields.h
+++ b/ovn/lib/logical-fields.h
@@ -51,6 +51,7 @@ enum mff_log_flags_bits {
     MLF_FORCE_SNAT_FOR_LB_BIT = 3,
     MLF_LOCAL_ONLY_BIT = 4,
     MLF_NESTED_CONTAINER_BIT = 5,
+    MLF_FROM_CTRL_BIT = 16,
 };
 
 /* MFF_LOG_FLAGS_REG flag assignments */
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index c548faf94..0c09b9dcb 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -3907,7 +3907,8 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows,
     if (ls_has_dns_records(od->nbs)) {
         const char *actions = has_stateful ? "ct_commit; next;" : "next;";
         ovn_lflow_add(
-            lflows, od, S_SWITCH_OUT_ACL, 34000, "udp.src == 53",
+            lflows, od, S_SWITCH_OUT_ACL, 34000,
+            "flags.from_ctrl && udp.src == 53",
             actions);
     }
 }
-- 
2.43.0

openSUSE Build Service is sponsored by