mirror of
https://github.com/openvswitch/ovs
synced 2025-10-17 14:28:02 +00:00
odp-util: Fix segfault in MPLS attribute parsing.
Just because the ethertype is MPLS, this doesn't mean that the datapath understands and provides OVS_KEY_ATTR_MPLS attributes for the flow. Previously we would check the size of the OVS_KEY_ATTR_MPLS attribute before checking whether the attribute is present. This would cause a segfault in nl_attr_get_size(), usually triggered from a handler thread. This patch brings the MPLS parsing code more in line with the rest of the parse_l2_5_onward() function, by only processing MPLS if the attribute is present. Reported-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: Joe Stringer <joestringer@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -3038,6 +3038,10 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
|
||||
enum ovs_key_attr expected_bit = 0xff;
|
||||
|
||||
if (eth_type_mpls(src_flow->dl_type)) {
|
||||
if (!is_mask || present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS)) {
|
||||
expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_MPLS);
|
||||
}
|
||||
if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS)) {
|
||||
size_t size = nl_attr_get_size(attrs[OVS_KEY_ATTR_MPLS]);
|
||||
const ovs_be32 *mpls_lse = nl_attr_get(attrs[OVS_KEY_ATTR_MPLS]);
|
||||
int n = size / sizeof(ovs_be32);
|
||||
@@ -3046,19 +3050,9 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
|
||||
if (!size || size % sizeof(ovs_be32)) {
|
||||
return ODP_FIT_ERROR;
|
||||
}
|
||||
|
||||
if (!is_mask) {
|
||||
expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_MPLS);
|
||||
|
||||
if (!(present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS))) {
|
||||
return ODP_FIT_TOO_LITTLE;
|
||||
}
|
||||
} else if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_MPLS)) {
|
||||
if (flow->mpls_lse[0] && flow->dl_type != htons(0xffff)) {
|
||||
return ODP_FIT_ERROR;
|
||||
}
|
||||
expected_attrs |= (UINT64_C(1) << OVS_KEY_ATTR_MPLS);
|
||||
}
|
||||
|
||||
for (i = 0; i < n && i < FLOW_MAX_MPLS_LABELS; i++) {
|
||||
flow->mpls_lse[i] = mpls_lse[i];
|
||||
@@ -3081,6 +3075,7 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
|
||||
return ODP_FIT_TOO_LITTLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goto done;
|
||||
} else if (src_flow->dl_type == htons(ETH_TYPE_IP)) {
|
||||
|
Reference in New Issue
Block a user