Currently, any UDP-encapsulated packet of 8 bytes or less will be passed to userspace, whether it starts with the non-ESP prefix or not (except keepalives). This includes: - messages of 1, 2, 3 bytes - messages of 4 to 8 bytes not starting with 00 00 00 00
This patch changes that behavior, so that only properly-formed non-ESP messages are passed to userspace. Messages of 8 bytes or less that don't contain a full non-ESP prefix followed by some data (at least one byte) will be dropped and counted as XfrmInHdrError. Signed-off-by: Sabrina Dubroca <s...@queasysnail.net> --- net/ipv4/xfrm4_input.c | 9 +++++++-- net/ipv6/xfrm6_input.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index ad2afeef4f10..2a2bb38ac798 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c @@ -114,9 +114,14 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) { /* ESP Packet without Non-ESP header */ len = sizeof(struct udphdr); - } else - /* Must be an IKE packet.. pass it through */ + } else if (len > 4 && udpdata32[0] == 0) { + /* IKE packet: pass it through */ return 1; + } else { + /* incomplete packet, drop */ + XFRM_INC_STATS(dev_net(skb->dev), LINUX_MIB_XFRMINHDRERROR); + goto drop; + } break; case UDP_ENCAP_ESPINUDP_NON_IKE: /* Check if this is a keepalive packet. If so, eat it. */ diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 04cbeefd8982..7e14d59d55cb 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -110,9 +110,14 @@ int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) { /* ESP Packet without Non-ESP header */ len = sizeof(struct udphdr); - } else - /* Must be an IKE packet.. pass it through */ + } else if (len > 4 && udpdata32[0] == 0) { + /* IKE packet: pass it through */ return 1; + } else { + /* incomplete packet, drop */ + XFRM_INC_STATS(dev_net(skb->dev), LINUX_MIB_XFRMINHDRERROR); + goto drop; + } break; case UDP_ENCAP_ESPINUDP_NON_IKE: /* Check if this is a keepalive packet. If so, eat it. */ -- 2.27.0