Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
4cf0215a51
!194 fix CVE-2022-2639
From: @yangl777 
Reviewed-by: @robertxw 
Signed-off-by: @robertxw
2024-03-29 07:19:25 +00:00
yangl777
97b14837cb fix CVE-2022-2639 2024-03-29 06:35:13 +00:00
openeuler-ci-bot
ef65f3b6bf
!187 fix CVE-2023-3966
From: @zppzhangpan 
Reviewed-by: @robertxw 
Signed-off-by: @robertxw
2024-02-20 11:48:57 +00:00
zppzhangpan
a4fc4faf0a fix CVE-2023-3966 2024-02-20 18:54:18 +08:00
openeuler-ci-bot
71ce7b6760
!178 [sync] PR-175: fix file conflicts
From: @openeuler-sync-bot 
Reviewed-by: @robertxw 
Signed-off-by: @robertxw
2023-12-18 06:55:49 +00:00
zhouwenpei
57b9a1e786 fix file conflicts
(cherry picked from commit 3074a732c00c24ec85c44c19de06d39dd28a5da4)
2023-12-18 14:41:47 +08:00
openeuler-ci-bot
f61a058616
!170 repair service startup failed
From: @zhouwenpei 
Reviewed-by: @robertxw 
Signed-off-by: @robertxw
2023-11-21 09:30:21 +00:00
zhouwenpei
2d3fb6daaf repair service startup failed 2023-11-21 08:53:34 +00:00
openeuler-ci-bot
1c51ca97bd
!166 [sync] PR-165: fix CVE-2023-5366
From: @openeuler-sync-bot 
Reviewed-by: @sunsuwan 
Signed-off-by: @sunsuwan
2023-10-13 06:22:00 +00:00
zhouwenpei
77e1db4e6a fix CVE-2023-5366
(cherry picked from commit 1198e0866c30f0183621a9ebbcaa6bd0fa6d02ef)
2023-10-09 15:52:34 +08:00
7 changed files with 734 additions and 4 deletions

View File

@ -0,0 +1,160 @@
From 87f191a3a398ae495fa55d70ca5fe5d813bd284f Mon Sep 17 00:00:00 2001
From: Ilya Maximets <i.maximets@ovn.org>
Date: Sun, 14 Aug 2022 16:45:59 +0200
Subject: [PATCH] netdev-offload-tc: Fix the mask for tunnel metadata length.
'wc.masks.tunnel.metadata.present.len' must be a mask for the same
field in the flow key, but in the tc_flower structure it's the real
length of metadata masks.
That is correctly handled for the individual opt->length, setting all
the masks to 0x1f like it's done in the tun_metadata_to_geneve_mask__(),
but not handled for the main 'len' field.
Fix that by setting the mask to 0xff like it's done during the flow
translation in xlate_actions() and during the flow dump in the
tun_metadata_from_geneve_nlattr().
Also, flower always has an exact match on the present.len field
regardless of its value and regardless of this field being masked
by OVS flow translation layer while installing the flow. Hence,
all tunnel flows dumped from TC should have an exact match on
present.len and also UDPIF flag, because present.len doesn't make
sense without that flag. Without the change, zero-length options
match is incorrectly reported as a wildcard match. The side effect
though is that zero-length match on geneve options is reported even
for other tunnel types, e.g. vxlan. But that should be fairly
harmless. To avoid reporting a match on empty geneve options for
vxlan/etc. tunnels we'll need to check the tunnel port type, there
is no enough information in the TUNNEL attribute itself.
Extra checks and comments added around the code to better explain
what is going on.
Fixes: a468645c6d33 ("lib/tc: add geneve with option match offload")
Reviewed-by: Roi Dayan <roid@nvidia.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reference:https://github.com/openvswitch/ovs/commit/87f191a3a398ae495fa55d70ca5fe5d813bd284f
Conflict:Context adaptation
---
lib/netdev-offload-tc.c | 33 +++++++++++++++++++++++----------
lib/tc.c | 13 ++++++++++---
2 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 68c4c7e..2383fe2 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -476,30 +476,42 @@ flower_tun_opt_to_match(struct match *match, struct tc_flower *flower)
struct geneve_opt *opt, *opt_mask;
int len, cnt = 0;
+ /* Options are always in UDPIF format in the 'flower'. */
+ match->flow.tunnel.flags |= FLOW_TNL_F_UDPIF;
+ match->wc.masks.tunnel.flags |= FLOW_TNL_F_UDPIF;
+
+ match->flow.tunnel.metadata.present.len =
+ flower->key.tunnel.metadata.present.len;
+ /* In the 'flower' mask len is an actual length, not a mask. But in the
+ * 'match' it is an actual mask, so should be an exact match, because TC
+ * will always match on the exact value. */
+ match->wc.masks.tunnel.metadata.present.len = 0xff;
+
+ if (!flower->key.tunnel.metadata.present.len) {
+ /* No options present. */
+ return;
+ }
+
memcpy(match->flow.tunnel.metadata.opts.gnv,
flower->key.tunnel.metadata.opts.gnv,
flower->key.tunnel.metadata.present.len);
- match->flow.tunnel.metadata.present.len =
- flower->key.tunnel.metadata.present.len;
- match->flow.tunnel.flags |= FLOW_TNL_F_UDPIF;
memcpy(match->wc.masks.tunnel.metadata.opts.gnv,
flower->mask.tunnel.metadata.opts.gnv,
flower->mask.tunnel.metadata.present.len);
+ /* Fixing up 'length' fields of particular options, since these are
+ * also not masks, but actual lengths in the 'flower' structure. */
len = flower->key.tunnel.metadata.present.len;
while (len) {
opt = &match->flow.tunnel.metadata.opts.gnv[cnt];
opt_mask = &match->wc.masks.tunnel.metadata.opts.gnv[cnt];
+ /* "Exact" match as set in tun_metadata_to_geneve_mask__(). */
opt_mask->length = 0x1f;
cnt += sizeof(struct geneve_opt) / 4 + opt->length;
len -= sizeof(struct geneve_opt) + opt->length * 4;
}
-
- match->wc.masks.tunnel.metadata.present.len =
- flower->mask.tunnel.metadata.present.len;
- match->wc.masks.tunnel.flags |= FLOW_TNL_F_UDPIF;
}
static int
@@ -621,9 +633,8 @@ parse_tc_flower_to_match(struct tc_flower *flower,
if (flower->key.tunnel.tp_dst) {
match_set_tun_tp_dst(match, flower->key.tunnel.tp_dst);
}
- if (flower->key.tunnel.metadata.present.len) {
- flower_tun_opt_to_match(match, flower);
- }
+
+ flower_tun_opt_to_match(match, flower);
}
act_off = nl_msg_start_nested(buf, OVS_FLOW_ATTR_ACTIONS);
@@ -1079,6 +1090,8 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
len -= sizeof(struct geneve_opt) + opt->length * 4;
}
+ /* Copying from the key and not from the mask, since in the 'flower'
+ * the length for a mask is not a mask, but the actual length. */
flower->mask.tunnel.metadata.present.len = tnl->metadata.present.len;
}
diff --git a/lib/tc.c b/lib/tc.c
index 1e9810f..ef6138f 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -588,15 +588,17 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key,
const struct geneve_opt *opt, *opt_mask;
int len, cnt = 0;
+ if (key->present.len != mask->present.len) {
+ goto bad_length;
+ }
+
len = key->present.len;
while (len) {
opt = &key->opts.gnv[cnt];
opt_mask = &mask->opts.gnv[cnt];
if (opt->length != opt_mask->length) {
- VLOG_ERR_RL(&error_rl,
- "failed to parse tun options; key/mask length differ");
- return EINVAL;
+ goto bad_length;
}
cnt += sizeof(struct geneve_opt) / 4 + opt->length;
@@ -604,6 +606,11 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key,
}
return 0;
+
+bad_length:
+ VLOG_ERR_RL(&error_rl,
+ "failed to parse tun options; key/mask length differ");
+ return EINVAL;
}
static int
--
2.33.0

View File

@ -0,0 +1,90 @@
From 6f322ccf8a9989905b7c29420239d5f6d81f0002 Mon Sep 17 00:00:00 2001
From: Ilya Maximets <i.maximets@ovn.org>
Date: Fri, 19 Aug 2022 21:51:27 +0200
Subject: [PATCH] netdev-offload-tc: Parse tunnel options only for geneve
ports.
Cited commit correctly fixed the issue of incorrect reporting
of zero-length geneve option matches as wildcarded. But as a
side effect, exact match on the metadata length was added to
every tunnel flow match, even if the tunnel is not geneve.
That doesn't generate any functional issues, but it maybe
confusing to see 'tunnel(...,geneve(),...)' while looking at
datapath flow dumps for, e.g., vxlan tunnel flows.
Fix that by checking the port type before parsing geneve options.
tunnel() attribute itself doesn't have enough information to
figure out the tunnel type.
Fixes: 7a6c8074c5d2 ("netdev-offload-tc: Fix the mask for tunnel metadata length.")
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Reviewed-by: Roi Dayan <roid@nvidia.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reference:https://github.com/openvswitch/ovs/commit/6f322ccf8a9989905b7c29420239d5f6d81f0002
Conflict: Implement terse dump support: The parse_tc_flower_to_match function has an extra parameter.
---
lib/netdev-offload-tc.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 2383fe2..b8c3738 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -515,7 +515,8 @@ flower_tun_opt_to_match(struct match *match, struct tc_flower *flower)
}
static int
-parse_tc_flower_to_match(struct tc_flower *flower,
+parse_tc_flower_to_match(const struct netdev *netdev,
+ struct tc_flower *flower,
struct match *match,
struct nlattr **actions,
struct dpif_flow_stats *stats,
@@ -634,7 +635,9 @@ parse_tc_flower_to_match(struct tc_flower *flower,
match_set_tun_tp_dst(match, flower->key.tunnel.tp_dst);
}
- flower_tun_opt_to_match(match, flower);
+ if (!strcmp(netdev_get_type(netdev), "geneve")) {
+ flower_tun_opt_to_match(match, flower);
+ }
}
act_off = nl_msg_start_nested(buf, OVS_FLOW_ATTR_ACTIONS);
@@ -760,8 +763,8 @@ netdev_tc_flow_dump_next(struct netdev_flow_dump *dump,
continue;
}
- if (parse_tc_flower_to_match(&flower, match, actions, stats, attrs,
- wbuffer)) {
+ if (parse_tc_flower_to_match(netdev, &flower, match, actions,
+ stats, attrs, wbuffer)) {
continue;
}
@@ -1145,7 +1148,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
flower.mask.tunnel.tos = tnl_mask->ip_tos;
flower.mask.tunnel.ttl = tnl_mask->ip_ttl;
flower.mask.tunnel.id = (tnl->flags & FLOW_TNL_F_KEY) ? tnl_mask->tun_id : 0;
- flower_match_to_tun_opt(&flower, tnl, tnl_mask);
+ if (!strcmp(netdev_get_type(netdev), "geneve")) {
+ flower_match_to_tun_opt(&flower, tnl, tnl_mask);
+ }
flower.tunnel = true;
}
memset(&mask->tunnel, 0, sizeof mask->tunnel);
@@ -1458,7 +1463,8 @@ netdev_tc_flow_get(struct netdev *netdev OVS_UNUSED,
}
in_port = netdev_ifindex_to_odp_port(ifindex);
- parse_tc_flower_to_match(&flower, match, actions, stats, attrs, buf);
+ parse_tc_flower_to_match(netdev, &flower, match, actions,
+ stats, attrs, buf);
match->wc.masks.in_port.odp_port = u32_to_odp(UINT32_MAX);
match->flow.in_port.odp_port = in_port;
--
2.33.0

View File

@ -0,0 +1,138 @@
From b8657dada9641fbd2bd3a3f882e0862448d60910 Mon Sep 17 00:00:00 2001
From: Timothy Redaelli <tredaelli@redhat.com>
Date: Thu, 23 Nov 2023 19:47:54 +0100
Subject: [PATCH] netdev-offload-tc: Check geneve metadata length.
Currently ovs-vswitchd crashes, with hw offloading enabled, if a geneve
packet with corrupted metadata is received, because the metadata header
is not verified correctly.
This commit adds a check for geneve metadata length and, if the header
is wrong, the packet is not sent to flower.
It also includes a system-traffic test for geneve packets with corrupted
metadata.
Fixes: a468645c6d33 ("lib/tc: add geneve with option match offload")
Reported-by: Haresh Khandelwal <hakhande@redhat.com>
Signed-off-by: Timothy Redaelli <tredaelli@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reference:https://github.com/openvswitch/ovs/commit/b8657dada9641fbd2bd3a3f882e0862448d60910
Conflict:The return value is not modified in flower_match_to_tun_opt function
---
lib/netdev-offload-tc.c | 21 +++++++++++++++++---
tests/system-offloads-traffic.at | 34 ++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index b8c3738..e248d0b 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -42,6 +42,7 @@
VLOG_DEFINE_THIS_MODULE(netdev_offload_tc);
static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(60, 5);
+static struct vlog_rate_limit warn_rl = VLOG_RATE_LIMIT_INIT(10, 2);
static struct hmap ufid_tc = HMAP_INITIALIZER(&ufid_tc);
static bool multi_mask_per_prio = false;
@@ -1068,12 +1069,12 @@ test_key_and_mask(struct match *match)
return 0;
}
-static void
+static int
flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
const struct flow_tnl *tnl_mask)
{
struct geneve_opt *opt, *opt_mask;
- int len, cnt = 0;
+ int tot_opt_len, len, cnt = 0;
memcpy(flower->key.tunnel.metadata.opts.gnv, tnl->metadata.opts.gnv,
tnl->metadata.present.len);
@@ -1084,7 +1085,16 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
len = flower->key.tunnel.metadata.present.len;
while (len) {
+ if (len < sizeof *opt) {
+ return EOPNOTSUPP;
+ }
+
opt = &flower->key.tunnel.metadata.opts.gnv[cnt];
+ tot_opt_len = sizeof *opt + opt->length * 4;
+ if (len < tot_opt_len) {
+ return EOPNOTSUPP;
+ }
+
opt_mask = &flower->mask.tunnel.metadata.opts.gnv[cnt];
opt_mask->length = opt->length;
@@ -1096,6 +1106,7 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
/* Copying from the key and not from the mask, since in the 'flower'
* the length for a mask is not a mask, but the actual length. */
flower->mask.tunnel.metadata.present.len = tnl->metadata.present.len;
+ return 0;
}
static int
@@ -1149,7 +1160,11 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
flower.mask.tunnel.ttl = tnl_mask->ip_ttl;
flower.mask.tunnel.id = (tnl->flags & FLOW_TNL_F_KEY) ? tnl_mask->tun_id : 0;
if (!strcmp(netdev_get_type(netdev), "geneve")) {
- flower_match_to_tun_opt(&flower, tnl, tnl_mask);
+ err = flower_match_to_tun_opt(&flower, tnl, tnl_mask);
+ if (err) {
+ VLOG_WARN_RL(&warn_rl, "Unable to parse geneve options");
+ return err;
+ }
}
flower.tunnel = true;
}
diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at
index bfad66e..9643535 100644
--- a/tests/system-offloads-traffic.at
+++ b/tests/system-offloads-traffic.at
@@ -116,3 +116,37 @@ matchall
])
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
+
+AT_SETUP([offloads - handling of geneve corrupted metadata - offloads enabled])
+OVS_CHECK_GENEVE()
+
+OVS_TRAFFIC_VSWITCHD_START(
+ [_ADD_BR([br-underlay]) -- \
+ set bridge br0 other-config:hwaddr=f2:ff:00:00:00:01 -- \
+ set bridge br-underlay other-config:hwaddr=f2:ff:00:00:00:02])
+
+AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true])
+
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
+AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])
+
+ADD_NAMESPACES(at_ns0)
+
+dnl Set up underlay link from host into the namespace using veth pair.
+ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24", f2:ff:00:00:00:03)
+AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
+AT_CHECK([ip link set dev br-underlay up])
+
+dnl Set up tunnel endpoints on OVS outside the namespace and with a native
+dnl linux device inside the namespace.
+ADD_OVS_TUNNEL([geneve], [br0], [at_gnv0], [172.31.1.1], [10.1.1.100/24])
+ADD_NATIVE_TUNNEL([geneve], [ns_gnv0], [at_ns0], [172.31.1.100], [10.1.1.1/24],
+ [vni 0], [address f2:ff:00:00:00:04])
+
+NS_CHECK_EXEC([at_ns0], [$PYTHON3 $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 03 08 00 45 00 00 52 00 01 00 00 40 11 1f f7 ac 1f 01 01 ac 1f 01 64 de c1 17 c1 00 3e 59 e9 01 00 65 58 00 00 00 00 00 03 00 02 f2 ff 00 00 00 01 f2 ff 00 00 00 04 08 00 45 00 00 1c 00 01 00 00 40 01 64 7a 0a 01 01 01 0a 01 01 64 08 00 f7 ff 00 00 00 00 > /dev/null])
+
+OVS_WAIT_UNTIL([grep -q 'Invalid Geneve tunnel metadata' ovs-vswitchd.log])
+
+OVS_TRAFFIC_VSWITCHD_STOP(["/Invalid Geneve tunnel metadata on bridge br0 while processing icmp,in_port=1,vlan_tci=0x0000,dl_src=f2:ff:00:00:00:04,dl_dst=f2:ff:00:00:00:01,nw_src=10.1.1.1,nw_dst=10.1.1.100,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,icmp_type=8,icmp_code=0/d
+/Unable to parse geneve options/d"])
+AT_CLEANUP
--
2.33.0

View File

@ -0,0 +1,36 @@
From cefa91b2332d7009bc0be5d951d6cbbf349f90f8 Mon Sep 17 00:00:00 2001
From: Paolo Valerio <pvalerio@redhat.com>
Date: Fri, 15 Apr 2022 10:08:41 +0200
Subject: [PATCH] openvswitch: fix OOB access in reserve_sfa_size()
Given a sufficiently large number of actions, while copying and
reserving memory for a new action of a new flow, if next_offset is
greater than MAX_ACTIONS_BUFSIZE, the function reserve_sfa_size() does
not return -EMSGSIZE as expected, but it allocates MAX_ACTIONS_BUFSIZE
bytes increasing actions_len by req_size. This can then lead to an OOB
write access, especially when further actions need to be copied.
Fix it by rearranging the flow action size check.
Conflict:NA
Reference:https://github.com/torvalds/linux/commit/cefa91b2332d7009bc0be5d951d6cbbf349f90f8
---
datapath/flow_netlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 0f7ab53..1f04072 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -2322,7 +2322,7 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2);
if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
- if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) {
+ if ((next_offset + req_size) > MAX_ACTIONS_BUFSIZE) {
OVS_NLERR(log, "Flow action size exceeds max %u",
MAX_ACTIONS_BUFSIZE);
return ERR_PTR(-EMSGSIZE);
--
2.33.0

View File

@ -0,0 +1,233 @@
From 489553b1c21692063931a9f50b6849b23128443c Mon Sep 17 00:00:00 2001
From: Ilya Maximets <i.maximets@ovn.org>
Date: Fri, 17 Feb 2023 21:09:59 +0100
Subject: [PATCH] classifier: Fix missing masks on a final stage with ports
trie.
Flow lookup doesn't include masks of the final stage in a resulting
flow wildcards in case that stage had L4 ports match. Only the result
of ports trie lookup is added to the mask. It might be sufficient in
many cases, but it's not correct, because ports trie is not how we
decided that the packet didn't match in this subtable. In fact, we
used a full subtable mask in order to determine that, so all the
subtable mask bits has to be added.
Ports trie can still be used to adjust ports' mask, but it is not
sufficient to determine that the packet didn't match.
Assuming we have following 2 OpenFlow rules on the bridge:
table=0, priority=10,tcp,tp_dst=80,tcp_flags=+psh actions=drop
table=0, priority=0 actions=output(1)
The first high priority rule supposed to drop all the TCP data traffic
sent on port 80. The handshake, however, is allowed for forwarding.
Both 'tcp_flags' and 'tp_dst' are on the final stage in the flow.
Since the stage mask from that stage is not incorporated into the flow
wildcards and only ports mask is getting updated, we have the following
megaflow for the SYN packet that has no match on 'tcp_flags':
$ ovs-appctl ofproto/trace br0 "in_port=br0,tcp,tp_dst=80,tcp_flags=syn"
Megaflow: recirc_id=0,eth,tcp,in_port=LOCAL,nw_frag=no,tp_dst=80
Datapath actions: 1
If this flow is getting installed into datapath flow table, all the
packets for port 80, regardless of TCP flags, will be forwarded.
Incorporating all the looked at bits from the final stage into the
stages map in order to get all the necessary wildcards. Ports mask
has to be updated as a last step, because it doesn't cover the full
64-bit slot in the flowmap.
With this change, in the example above, OVS is producing correct
flow wildcards including match on TCP flags:
Megaflow: recirc_id=0,eth,tcp,in_port=LOCAL,nw_frag=no,tp_dst=80,tcp_flags=-psh
Datapath actions: 1
This way only -psh packets will be forwarded, as expected.
This issue affects all other fields on stage 4, not only TCP flags.
Tests included to cover tcp_flags, nd_target and ct_tp_src/dst.
First two are frequently used, ct ones are sharing the same flowmap
slot with L4 ports, so important to test.
Before the pre-computation of stage masks, flow wildcards were updated
during lookup, so there was no issue. The bits of the final stage was
lost with introduction of 'stages_map'.
Recent adjustment of segment boundaries exposed 'tcp_flags' to the issue.
Reported-at: https://github.com/openvswitch/ovs-issues/issues/272
Fixes: ca44218515f0 ("classifier: Adjust segment boundary to execute prerequisite processing.")
Fixes: fa2fdbf8d0c1 ("classifier: Pre-compute stage masks.")
Acked-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
lib/classifier.c | 25 ++++++++++---
tests/classifier.at | 88 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+), 5 deletions(-)
diff --git a/lib/classifier.c b/lib/classifier.c
index 0a89626cc30..18dbfc83ad4 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -1695,6 +1695,8 @@ find_match_wc(const struct cls_subtable *subtable, ovs_version_t version,
const struct cls_match *rule = NULL;
struct flowmap stages_map = FLOWMAP_EMPTY_INITIALIZER;
unsigned int mask_offset = 0;
+ bool adjust_ports_mask = false;
+ ovs_be32 ports_mask;
int i;
/* Try to finish early by checking fields in segments. */
@@ -1722,6 +1724,9 @@ find_match_wc(const struct cls_subtable *subtable, ovs_version_t version,
subtable->index_maps[i], flow, wc)) {
goto no_match;
}
+ /* Accumulate the map used so far. */
+ stages_map = flowmap_or(stages_map, subtable->index_maps[i]);
+
hash = flow_hash_in_minimask_range(flow, &subtable->mask,
subtable->index_maps[i],
&mask_offset, &basis);
@@ -1731,14 +1736,16 @@ find_match_wc(const struct cls_subtable *subtable, ovs_version_t version,
* unwildcarding all the ports bits, use the ports trie to figure out a
* smaller set of bits to unwildcard. */
unsigned int mbits;
- ovs_be32 value, plens, mask;
+ ovs_be32 value, plens;
- mask = miniflow_get_ports(&subtable->mask.masks);
- value = ((OVS_FORCE ovs_be32 *)flow)[TP_PORTS_OFS32] & mask;
+ ports_mask = miniflow_get_ports(&subtable->mask.masks);
+ value = ((OVS_FORCE ovs_be32 *) flow)[TP_PORTS_OFS32] & ports_mask;
mbits = trie_lookup_value(&subtable->ports_trie, &value, &plens, 32);
- ((OVS_FORCE ovs_be32 *)&wc->masks)[TP_PORTS_OFS32] |=
- mask & be32_prefix_mask(mbits);
+ ports_mask &= be32_prefix_mask(mbits);
+ ports_mask |= ((OVS_FORCE ovs_be32 *) &wc->masks)[TP_PORTS_OFS32];
+
+ adjust_ports_mask = true;
goto no_match;
}
@@ -1751,6 +1758,14 @@ find_match_wc(const struct cls_subtable *subtable, ovs_version_t version,
/* Unwildcard the bits in stages so far, as they were used in determining
* there is no match. */
flow_wildcards_fold_minimask_in_map(wc, &subtable->mask, stages_map);
+ if (adjust_ports_mask) {
+ /* This has to be done after updating flow wildcards to overwrite
+ * the ports mask back. We can't simply disable the corresponding bit
+ * in the stages map, because it has 64-bit resolution, i.e. one
+ * bit covers not only tp_src/dst, but also ct_tp_src/dst, which are
+ * not covered by the trie. */
+ ((OVS_FORCE ovs_be32 *) &wc->masks)[TP_PORTS_OFS32] = ports_mask;
+ }
return NULL;
}
diff --git a/tests/classifier.at b/tests/classifier.at
index f652b59837b..de2705653e0 100644
--- a/tests/classifier.at
+++ b/tests/classifier.at
@@ -65,6 +65,94 @@ Datapath actions: 2
OVS_VSWITCHD_STOP
AT_CLEANUP
+AT_SETUP([flow classifier - lookup segmentation - final stage])
+OVS_VSWITCHD_START
+add_of_ports br0 1 2 3
+AT_DATA([flows.txt], [dnl
+table=0 in_port=1 priority=33,tcp,tp_dst=80,tcp_flags=+psh,action=output(2)
+table=0 in_port=1 priority=0,ip,action=drop
+table=0 in_port=2 priority=16,icmp6,nw_ttl=255,icmp_type=135,icmp_code=0,nd_target=1000::1 ,action=output(1)
+table=0 in_port=2 priority=0,ip,action=drop
+table=0 in_port=3 action=resubmit(,1)
+table=1 in_port=3 priority=45,ct_state=+trk+rpl,ct_nw_proto=6,ct_tp_src=3/0x1,tcp,tp_dst=80,tcp_flags=+psh,action=output(2)
+table=1 in_port=3 priority=10,ip,action=drop
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=syn'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=-psh
+Datapath actions: drop
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=syn|ack'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=-psh
+Datapath actions: drop
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=ack|psh'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=+psh
+Datapath actions: 2
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=80,tcp_flags=-psh
+Datapath actions: drop
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=0x40/0xfff0,tcp_flags=-psh
+Datapath actions: drop
+])
+
+dnl Having both the port and the tcp flags in the resulting megaflow below
+dnl is redundant, but that is how ports trie logic is implemented.
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=81'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_dst=81,tcp_flags=-psh
+Datapath actions: drop
+])
+
+dnl nd_target is redundant in the megaflow below and it is also not relevant
+dnl for an icmp reply. Datapath may discard that match, but it is OK as long
+dnl as we have prerequisites (icmp_type) in the match as well.
+AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=128,icmpv6_code=0"], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x80/0xfc,nd_target=::
+Datapath actions: drop
+])
+
+AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=135,icmpv6_code=0"], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=::
+Datapath actions: drop
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=135,icmpv6_code=0,nd_target=1000::1"], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=1000::1
+Datapath actions: 1
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=2,eth_src=f6:d2:b0:19:5e:7b,eth_dst=d2:49:19:91:78:fe,dl_type=0x86dd,ipv6_src=1000::3,ipv6_dst=1000::4,nw_proto=58,nw_ttl=255,icmpv6_type=135,icmpv6_code=0,nd_target=1000::2"], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,eth,icmp6,in_port=2,nw_ttl=255,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=1000::2
+Datapath actions: drop
+])
+
+dnl Check that ports' mask doesn't affect ct ports.
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=3,ct_state=trk|rpl,ct_nw_proto=6,ct_tp_src=3,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=80,tcp_flags=psh'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,ct_state=+rpl+trk,ct_nw_proto=6,ct_tp_src=0x1/0x1,eth,tcp,in_port=3,nw_frag=no,tp_dst=80,tcp_flags=+psh
+Datapath actions: 2
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=3,ct_state=trk|rpl,ct_nw_proto=6,ct_tp_src=3,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=79,tcp_flags=psh'], [0], [stdout])
+AT_CHECK([tail -2 stdout], [0],
+ [Megaflow: recirc_id=0,ct_state=+rpl+trk,ct_nw_proto=6,ct_tp_src=0x1/0x1,eth,tcp,in_port=3,nw_frag=no,tp_dst=0x40/0xfff0,tcp_flags=+psh
+Datapath actions: drop
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
AT_BANNER([flow classifier prefix lookup])
AT_SETUP([flow classifier - prefix lookup])
OVS_VSWITCHD_START

41
fix-selinux-err.patch Normal file
View File

@ -0,0 +1,41 @@
From 3b35964c7da2a4000486c57e2c347c8cc67ac393 Mon Sep 17 00:00:00 2001
Date: Wed, 1 Sep 2021 16:54:34 +0800
Subject: [PATCH] openvswitch-2
---
selinux/openvswitch-custom.te.in | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/selinux/openvswitch-custom.te.in b/selinux/openvswitch-custom.te.in
index b2c63ab..8f76c14 100644
--- a/selinux/openvswitch-custom.te.in
+++ b/selinux/openvswitch-custom.te.in
@@ -15,10 +15,12 @@ require {
type ifconfig_exec_t;
type init_t;
type init_var_run_t;
+ type initrc_t;
type insmod_exec_t;
type kernel_t;
type hostname_exec_t;
type modules_conf_t;
+ type modules_dep_t;
type modules_object_t;
type passwd_file_t;
type plymouth_exec_t;
@@ -117,10 +119,12 @@ allow openvswitch_t openvswitch_load_module_t:process transition;
allow openvswitch_load_module_t bin_t:file { execute execute_no_trans map };
allow openvswitch_load_module_t init_t:unix_stream_socket { getattr ioctl read write };
allow openvswitch_load_module_t init_var_run_t:dir { getattr read open search };
+allow openvswitch_load_module_t initrc_t:fifo_file ioctl;
allow openvswitch_load_module_t insmod_exec_t:file { execute execute_no_trans getattr map open read };
allow openvswitch_load_module_t kernel_t:system module_request;
allow openvswitch_load_module_t modules_conf_t:dir { getattr open read search };
allow openvswitch_load_module_t modules_conf_t:file { getattr open read };
+allow openvswitch_load_module_t modules_dep_t:file { getattr map open read };
allow openvswitch_load_module_t modules_object_t:file { map getattr open read };
allow openvswitch_load_module_t modules_object_t:dir { getattr open read search };
allow openvswitch_load_module_t openvswitch_load_module_exec_t:file { entrypoint };
--
2.27.0

View File

@ -3,15 +3,23 @@ Summary: Production Quality, Multilayer Open Virtual Switch
URL: http://www.openvswitch.org/ URL: http://www.openvswitch.org/
Version: 2.12.4 Version: 2.12.4
License: ASL 2.0 and ISC License: ASL 2.0 and ISC
Release: 5 Release: 10
Source: https://www.openvswitch.org/releases/openvswitch-%{version}.tar.gz Source: https://www.openvswitch.org/releases/openvswitch-%{version}.tar.gz
Buildroot: /tmp/openvswitch-rpm Buildroot: /tmp/openvswitch-rpm
Patch0000: 0000-openvswitch-add-stack-protector-strong.patch Patch0000: 0000-openvswitch-add-stack-protector-strong.patch
Patch0001: 0001-Remove-unsupported-permission-names.patch Patch0001: 0001-Remove-unsupported-permission-names.patch
Patch0002: specifies-the-ovs-module-path.patch Patch0002: specifies-the-ovs-module-path.patch
Patch0003: change-the-name-of-the-ipsec-configuration-file.patch Patch0003: change-the-name-of-the-ipsec-configuration-file.patch
Patch0004: backport-CVE-2022-4338.patch
Patch0005: backport-CVE-2023-1668.patch Patch6000: backport-CVE-2022-4338.patch
Patch6001: backport-CVE-2023-1668.patch
Patch6002: backport-CVE-2023-5366.patch
Patch6003: backport-0001-CVE-2023-3966.patch
Patch6004: backport-0002-CVE-2023-3966.patch
Patch6005: backport-0003-CVE-2023-3966.patch
Patch6006: backport-CVE-2022-2639.patch
Patch9000: fix-selinux-err.patch
Requires: %{name}-help Requires: %{name}-help
Requires: logrotate hostname python >= 2.7 python2-six selinux-policy-targeted libsepol >= 3.1 Requires: logrotate hostname python >= 2.7 python2-six selinux-policy-targeted libsepol >= 3.1
@ -43,6 +51,7 @@ Summary: Open vSwitch python3 bindings
Requires: python3 python3-six Requires: python3 python3-six
obsoletes: python-openvswitch < 2.10.0-6 obsoletes: python-openvswitch < 2.10.0-6
Provides: python-openvswitch = %{version}-%{release} Provides: python-openvswitch = %{version}-%{release}
Conflicts: openvswitch < 2.12.4-8
%description -n python3-openvswitch %description -n python3-openvswitch
Python bindings for the Open vSwitch database Python bindings for the Open vSwitch database
@ -235,7 +244,6 @@ exit 0
/usr/sbin/ovsdb-server /usr/sbin/ovsdb-server
%{python3_sitelib}/ovs %{python3_sitelib}/ovs
%{python3_sitelib}/ovstest %{python3_sitelib}/ovstest
%{python3_sitearch}/ovs
/usr/share/openvswitch/bugtool-plugins/ /usr/share/openvswitch/bugtool-plugins/
/usr/share/openvswitch/python/ /usr/share/openvswitch/python/
/usr/share/openvswitch/scripts/ovs-bugtool-* /usr/share/openvswitch/scripts/ovs-bugtool-*
@ -284,6 +292,30 @@ exit 0
%doc LICENSE %doc LICENSE
%changelog %changelog
* Fri Mar 29 2024 yanglu <yanglu72@h-partners.com> - 2.12.4-10
- Type:CVE
- Id:CVE-2022-2639
- SUG:NA
- DESC:fix CVE-2022-2639
* Tue Feb 20 2024 zhangpan <zhangpan103@h-partners.com> - 2.12.4-9
- fix CVE-2023-3966
* Thu Dec 14 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.12.4-8
- Type:bugfix
- Id:NA
- SUG:NA
- DESC:fix file conflicts
* Tue Nov 21 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.12.4-7
- Type:bugfix
- Id:NA
- SUG:NA
- DESC:repair service startup failed
* Sat Oct 07 2023 zhouwenpei <zhouwenpei1@h-partners.com> - 2.12.4-6
- fix CVE-2023-5366
* Fri Apr 14 2023 zhangpan <zhangpan103@h-partners.com> - 2.12.4-5 * Fri Apr 14 2023 zhangpan <zhangpan103@h-partners.com> - 2.12.4-5
- fix changelog date error - fix changelog date error