From: Luka Gejak Supervision frames are only valid if terminated with a zero-length EOT TLV. The current check fails to reject non-EOT entries as the terminal TLV, potentially allowing malformed supervision traffic. Fix this by strictly requiring the terminal TLV to be HSR_TLV_EOT with a length of zero, and properly linearizing the TLV header before access. Assisted-by: Gemini:Gemini-3.1-flash Signed-off-by: Luka Gejak --- net/hsr/hsr_forward.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index 0aca859c88cb..eb89cc44eac0 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -82,35 +82,33 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb) hsr_sup_tag->tlv.HSR_TLV_length != sizeof(struct hsr_sup_payload)) return false; - /* Get next tlv */ + /* Get next TLV */ total_length += hsr_sup_tag->tlv.HSR_TLV_length; - if (!pskb_may_pull(skb, total_length)) + if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv))) return false; skb_pull(skb, total_length); hsr_sup_tlv = (struct hsr_sup_tlv *)skb->data; skb_push(skb, total_length); - /* if this is a redbox supervision frame we need to verify - * that more data is available - */ + /* If this is a RedBox supervision frame, verify additional data */ if (hsr_sup_tlv->HSR_TLV_type == PRP_TLV_REDBOX_MAC) { - /* tlv length must be a length of a mac address */ + /* TLV length must be the size of a MAC address */ if (hsr_sup_tlv->HSR_TLV_length != sizeof(struct hsr_sup_payload)) return false; - /* make sure another tlv follows */ + /* Make sure another TLV follows */ total_length += sizeof(struct hsr_sup_tlv) + hsr_sup_tlv->HSR_TLV_length; - if (!pskb_may_pull(skb, total_length)) + if (!pskb_may_pull(skb, total_length + sizeof(struct hsr_sup_tlv))) return false; - /* get next tlv */ + /* Get next TLV */ skb_pull(skb, total_length); hsr_sup_tlv = (struct hsr_sup_tlv *)skb->data; skb_push(skb, total_length); } - /* end of tlvs must follow at the end */ - if (hsr_sup_tlv->HSR_TLV_type == HSR_TLV_EOT && + /* Supervision frame must end with EOT TLV */ + if (hsr_sup_tlv->HSR_TLV_type != HSR_TLV_EOT || hsr_sup_tlv->HSR_TLV_length != 0) return false; -- 2.53.0 From: Luka Gejak In hsr_newlink(), a provided but invalid IFLA_HSR_INTERLINK attribute was silently ignored if __dev_get_by_index() returned NULL. This leads to incorrect RedBox topology creation without notifying the user. Fix this by returning -EINVAL and an extack message when the interlink attribute is present but cannot be resolved. Assisted-by: Gemini:Gemini-3.1-flash Reviewed-by: Felix Maurer Signed-off-by: Luka Gejak --- net/hsr/hsr_netlink.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c index db0b0af7a692..f0ca23da3ab9 100644 --- a/net/hsr/hsr_netlink.c +++ b/net/hsr/hsr_netlink.c @@ -76,9 +76,14 @@ static int hsr_newlink(struct net_device *dev, return -EINVAL; } - if (data[IFLA_HSR_INTERLINK]) + if (data[IFLA_HSR_INTERLINK]) { interlink = __dev_get_by_index(link_net, nla_get_u32(data[IFLA_HSR_INTERLINK])); + if (!interlink) { + NL_SET_ERR_MSG_MOD(extack, "Interlink does not exist"); + return -EINVAL; + } + } if (interlink && interlink == link[0]) { NL_SET_ERR_MSG_MOD(extack, "Interlink and Slave1 are the same"); -- 2.53.0