From nobody Sun Dec 14 05:54:02 2025 Received: from smtp.forwardemail.net (smtp.forwardemail.net [149.28.215.223]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D03C32F6592 for ; Sat, 13 Dec 2025 10:14:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=149.28.215.223 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765620847; cv=none; b=Y3NoWptVPEO+2DYcKCNva/vQdlB+A7a38u784VoH59/fMjYxc0UhziNhK909GKHecQbSIesmpRKmetu+XQh2yFlRvSfWSDWD7JGeVEmUW60/6CpsMfoym+ocVcxoaI/yWbPy4qWCvVcutwQzLIeJaL1DEUJ2RO/hrIfRdmmLyKA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765620847; c=relaxed/simple; bh=9lzVO6If0UtnERwkY+xkVr58h02c8XQPuta4ZwM2wfQ=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=ncjz/gUz+gea6SzJ2QOXbXgcNAQJh6fqlOyUxoY788b/j4W0u353b+i6GgwITahbPaYT7FMOLz4vHsSqYPbWyQ68m90MYTB/AQsXhYls6L36tr+hf46BwaqW5fMmd5bV1rs8wLfU+9dgBOZLuAaAtlpiQ1g7fZZNcfPklpVVWPY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ubuntu.com; spf=pass smtp.mailfrom=fe-bounces.ubuntu.com; dkim=pass (2048-bit key) header.d=ubuntu.com header.i=@ubuntu.com header.b=o8ovbwH/; arc=none smtp.client-ip=149.28.215.223 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ubuntu.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fe-bounces.ubuntu.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ubuntu.com header.i=@ubuntu.com header.b="o8ovbwH/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ubuntu.com; h=Content-Transfer-Encoding: MIME-Version: Message-ID: Date: Subject: Cc: To: From; q=dns/txt; s=fe-953a8a3ca9; t=1765620838; bh=WuJNSQ3/mwjeSko5QvWtASPtwrlMT6jMSC5uuopo+9o=; b=o8ovbwH/AqiZ+K2pba4bNj4yPUiZA+E/d3TSiHzDU7/CDxbewubAHmduVVATzMA3fCfa32714 uTpjX+Oyq55McAjHm9osUog69hSQP5cz8IIfw3MF8O80cV7tVoLpWI4aBB3MUrWAQ14gTfL/xWV u8ucm2CJLxyOoZDVqBJtDzNNBg9wvhhvGpfes6jOYlrETyumkNGv/vb3zCB1ubf9VXtBUAZ6ImR mHa8KI5ial3h7Gy7WA1r9Ug+fKxStgjPPM7BG9I6Ki8cuBzqORHgEDrr9kSRm/8hOLOEekvpk1I hErZYiFLZpNtB1rerGiyB3JjZUbddzEvFPoiFLohPdzA== X-Forward-Email-ID: 693d3c5afb4eeecc7f5b6f45 X-Forward-Email-Sender: rfc822; fnordahl@ubuntu.com, smtp.forwardemail.net, 149.28.215.223 X-Forward-Email-Version: 1.6.6 X-Forward-Email-Website: https://forwardemail.net X-Complaints-To: abuse@forwardemail.net X-Report-Abuse: abuse@forwardemail.net X-Report-Abuse-To: abuse@forwardemail.net From: Frode Nordahl To: "David S. Miller" , David Ahern , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Tariq Toukan , Cosmin Ratiu , Gal Pressman , Kees Cook Cc: Frode Nordahl , stable@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net v2] erspan: Initialize options_len before referencing options. Date: Sat, 13 Dec 2025 10:13:36 +0000 Message-ID: <20251213101338.4693-1-fnordahl@ubuntu.com> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The struct ip_tunnel_info has a flexible array member named options that is protected by a counted_by(options_len) attribute. The compiler will use this information to enforce runtime bounds checking deployed by FORTIFY_SOURCE string helpers. As laid out in the GCC documentation, the counter must be initialized before the first reference to the flexible array member. After scanning through the files that use struct ip_tunnel_info and also refer to options or options_len, it appears the normal case is to use the ip_tunnel_info_opts_set() helper. Said helper would initialize options_len properly before copying data into options, however in the GRE ERSPAN code a partial update is done, preventing the use of the helper function. Before this change the handling of ERSPAN traffic in GRE tunnels would cause a kernel panic when the kernel is compiled with GCC 15+ and having FORTIFY_SOURCE configured: memcpy: detected buffer overflow: 4 byte write of buffer size 0 Call Trace: __fortify_panic+0xd/0xf erspan_rcv.cold+0x68/0x83 ? ip_route_input_slow+0x816/0x9d0 gre_rcv+0x1b2/0x1c0 gre_rcv+0x8e/0x100 ? raw_v4_input+0x2a0/0x2b0 ip_protocol_deliver_rcu+0x1ea/0x210 ip_local_deliver_finish+0x86/0x110 ip_local_deliver+0x65/0x110 ? ip_rcv_finish_core+0xd6/0x360 ip_rcv+0x186/0x1a0 Cc: stable@vger.kernel.org Link: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#in= dex-counted_005fby-variable-attribute Reported-at: https://launchpad.net/bugs/2129580 Fixes: bb5e62f2d547 ("net: Add options as a flexible array to struct ip_tun= nel_info") Signed-off-by: Frode Nordahl --- v2: - target correct netdev tree and properly cc stable in commit message. - replace repeated long in-line comments and link with a single line. - document search for any similar offenses in the code base in commit message. v1: https://lore.kernel.org/all/20251212073202.13153-1-fnordahl@ubuntu.com/ net/ipv4/ip_gre.c | 6 ++++-- net/ipv6/ip6_gre.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 761a53c6a89a..8178c44a3cdd 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -330,6 +330,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, if (!tun_dst) return PACKET_REJECT; =20 + /* MUST set options_len before referencing options */ + info =3D &tun_dst->u.tun_info; + info->options_len =3D sizeof(*md); + /* skb can be uncloned in __iptunnel_pull_header, so * old pkt_md is no longer valid and we need to reset * it @@ -344,10 +348,8 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_= ptk_info *tpi, memcpy(md2, pkt_md, ver =3D=3D 1 ? ERSPAN_V1_MDSIZE : ERSPAN_V2_MDSIZE); =20 - info =3D &tun_dst->u.tun_info; __set_bit(IP_TUNNEL_ERSPAN_OPT_BIT, info->key.tun_flags); - info->options_len =3D sizeof(*md); } =20 skb_reset_mac_header(skb); diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index c82a75510c0e..4603554d4c7f 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -535,6 +535,10 @@ static int ip6erspan_rcv(struct sk_buff *skb, if (!tun_dst) return PACKET_REJECT; =20 + /* MUST set options_len before referencing options */ + info =3D &tun_dst->u.tun_info; + info->options_len =3D sizeof(*md); + /* skb can be uncloned in __iptunnel_pull_header, so * old pkt_md is no longer valid and we need to reset * it @@ -543,7 +547,6 @@ static int ip6erspan_rcv(struct sk_buff *skb, skb_network_header_len(skb); pkt_md =3D (struct erspan_metadata *)(gh + gre_hdr_len + sizeof(*ershdr)); - info =3D &tun_dst->u.tun_info; md =3D ip_tunnel_info_opts(info); md->version =3D ver; md2 =3D &md->u.md2; @@ -551,7 +554,6 @@ static int ip6erspan_rcv(struct sk_buff *skb, ERSPAN_V2_MDSIZE); __set_bit(IP_TUNNEL_ERSPAN_OPT_BIT, info->key.tun_flags); - info->options_len =3D sizeof(*md); =20 ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); =20 --=20 2.51.0