From: Weiming Shi <bestswngs@gmail.com>
To: "David S . Miller" <davem@davemloft.net>,
David Ahern <dsahern@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>, Kees Cook <kees@kernel.org>,
"Gustavo A . R . Silva" <gustavoars@kernel.org>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org, bpf@vger.kernel.org,
Xiang Mei <xmei5@asu.edu>, Weiming Shi <bestswngs@gmail.com>,
stable@vger.kernel.org, co+beaa1ed2d7aaec16@bugs.sh
Subject: [PATCH net] net: initialize ICMP error queue opt_stats
Date: Wed, 11 Nov 2026 09:05:30 -0800 [thread overview]
Message-ID: <20261111170528.495116-3-bestswngs@gmail.com> (raw)
ip_icmp_error() and ipv6_icmp_error() clone a received ICMP skb before
building its error queue entry. skb_clone() preserves the complete control
buffer, while the IP receive paths initialize only the portion aliased by
sock_exterr_skb::header. The two functions initialize ee, addr_offset, and
port, but leave the final byte containing opt_stats and unused untouched.
A TCX classifier can leave bpf_skb_data_end::data_end across that byte,
forging opt_stats and making __sock_recv_timestamp() pass skb->len bytes
from skb->data to put_cmsg(). For a non-linear ICMP skb, this reads beyond
its linear head.
Initialize both bitfields in the two clone-based producers. Do not clear
the whole sock_exterr_skb because the error receive paths consume the saved
IP control-buffer header.
usercopy: Kernel memory exposure attempt detected from SLUB object
'skbuff_small_head' (offset 72, size 59964)!
kernel BUG at mm/usercopy.c:102!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
RIP: usercopy_abort (mm/usercopy.c:102)
Call Trace:
__check_heap_object (mm/slub.c:8146)
__check_object_size (mm/usercopy.c:258)
put_cmsg (net/core/scm.c:276)
__sock_recv_timestamp (net/socket.c:1061)
ip_recv_error (net/ipv4/ip_sockglue.c:550)
udp_recvmsg (net/ipv4/udp.c:2034)
inet_recvmsg (net/ipv4/af_inet.c:896)
sock_recvmsg (net/socket.c:1159)
____sys_recvmsg (net/socket.c:2918)
___sys_recvmsg (net/socket.c:2961)
__sys_recvmsg (net/socket.c:2993)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
Kernel panic - not syncing: Fatal exception
With HARDENED_USERCOPY enabled, the reproducer aborted the unpatched kernel
on its first packet. With runtime usercopy checks disabled and KASAN left
in report mode, the same recvmsg() returned 59,964 control-message data
bytes sourced past a 704-byte skb head. Beyond offset 1,024, 58,932 bytes
differed from the prefilled userspace marker, including 6,288 nonzero
bytes. The patched build completed 2,000 packets under both configurations
without a forged SCM_TIMESTAMPING_OPT_STATS message or sanitizer report.
Networking selftests were not run.
Fixes: 4ef1b2869447 ("tcp: mark skbs with SCM_TIMESTAMPING_OPT_STATS")
Cc: stable@vger.kernel.org
Reported-by: <co+beaa1ed2d7aaec16@bugs.sh>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/ipv4/ip_sockglue.c | 2 ++
net/ipv6/datagram.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index a55ef327ec93..3ab84a4c31e5 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -429,6 +429,8 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
serr->addr_offset = (u8 *)&(((struct iphdr *)(icmp_hdr(skb) + 1))->daddr) -
skb_network_header(skb);
serr->port = port;
+ serr->opt_stats = 0;
+ serr->unused = 0;
if (skb_pull(skb, payload - skb->data)) {
if (inet_test_bit(RECVERR_RFC4884, sk))
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index ca3605acb433..85f646f8d059 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -330,6 +330,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
serr->addr_offset = (u8 *)&(((struct ipv6hdr *)(icmph + 1))->daddr) -
skb_network_header(skb);
serr->port = port;
+ serr->opt_stats = 0;
+ serr->unused = 0;
__skb_pull(skb, payload - skb->data);
--
2.56.0
next reply other threads:[~2026-11-11 17:06 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 17:05 Weiming Shi [this message]
2026-11-12 2:30 ` [PATCH net] net: initialize ICMP error queue opt_stats Hangbin Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261111170528.495116-3-bestswngs@gmail.com \
--to=bestswngs@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=co+beaa1ed2d7aaec16@bugs.sh \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=gustavoars@kernel.org \
--cc=horms@kernel.org \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@vger.kernel.org \
--cc=xmei5@asu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.