CVE-2026-46037
Description
In the Linux kernel, the following vulnerability has been resolved:
ipv4: icmp: validate reply type before using icmp_pointers
Extended echo replies use ICMP_EXT_ECHOREPLY as the outbound reply type. That value is outside the range covered by icmp_pointers[], which only describes the traditional ICMP types up to NR_ICMP_TYPES.
Avoid consulting icmp_pointers[] for reply types outside that range, and use array_index_nospec() for the remaining in-range lookup. Normal ICMP replies keep their existing behavior unchanged.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A Linux kernel ICMP handler validates the reply type before indexing into icmp_pointers[], preventing out-of-bounds access for extended echo replies.
Vulnerability
In the Linux kernel IPv4 ICMP implementation, the function that handles outgoing ICMP replies uses the icmp_pointers[] array to look up per-type handler information. For extended echo replies (ICMP_EXT_ECHOREPLY), the reply type value falls outside the range covered by icmp_pointers[], which only spans traditional ICMP types up to NR_ICMP_TYPES. Prior to the fix, the kernel did not validate the reply type before indexing into the array, leading to an out-of-bounds read. The commit bc64a66e0b9a addresses this by adding a bounds check and using array_index_nospec() for the in-range lookup, leaving normal ICMP replies unaffected [1]. The affected versions are those prior to the inclusion of this stable commit.
Exploitation
An attacker would need to trigger the kernel to generate an ICMP extended echo reply (ICMP_EXT_ECHOREPLY) as an outbound packet. This requires crafting an appropriate ICMP extended echo request that causes the kernel to reply using the extended reply type. The attacker must have network connectivity to send IP packets to the target system; no authentication is required. The vulnerability is triggered in the kernel's response path without requiring any special privilege beyond sending a network packet.
Impact
Successful exploitation allows an attacker to cause an out-of-bounds read in the kernel's ICMP handler. The out-of-bounds access can lead to memory corruption, kernel panic (denial of service), or potential information disclosure, depending on the kernel memory layout. In the worst case, this could enable privilege escalation if the attacker can control the read data to influence kernel behavior. The scope of compromise is at the kernel level, affecting all processes on the system.
Mitigation
The fix is included in Linux kernel stable commit bc64a66e0b9a [1]. Systems should apply the corresponding stable kernel update containing this commit as soon as it is available for their distribution. There is no reported workaround besides disabling ICMP extended echo support if feasible, but the vendor recommends updating to the patched kernel. The vulnerability is not currently listed on the CISA Known Exploited Vulnerabilities (KEV) catalog.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
1067bf002a2d73ipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 2f4fac22d1aba3..7eeff658b467aa 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -371,7 +372,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
92e7c209036dipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 3171392c8c066a..29c73b05b1e1ab 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -359,7 +360,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
bc64a66e0b9aipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 8e53b595a41948..4f55b6041feb49 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -361,7 +362,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
c2178ff1c70eipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 980aa17f3534d3..fc0a93f43313d1 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -362,7 +363,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
d700c34a5d18ipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 4e2a6c70dcd840..ba4b1eec9ea2da 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -373,7 +374,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
d700c34a5d18ipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 4e2a6c70dcd840..ba4b1eec9ea2da 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -373,7 +374,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
67bf002a2d73ipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 2f4fac22d1aba3..7eeff658b467aa 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -371,7 +372,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
92e7c209036dipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 3171392c8c066a..29c73b05b1e1ab 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -359,7 +360,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
c2178ff1c70eipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 980aa17f3534d3..fc0a93f43313d1 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -362,7 +363,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
bc64a66e0b9aipv4: icmp: validate reply type before using icmp_pointers
1 file changed · +4 −2
net/ipv4/icmp.c+4 −2 modifieddiff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 8e53b595a41948..4f55b6041feb49 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -64,6 +64,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/fcntl.h> +#include <linux/nospec.h> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> @@ -361,7 +362,9 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, to, len); skb->csum = csum_block_add(skb->csum, csum, odd); - if (icmp_pointers[icmp_param->data.icmph.type].error) + if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && + icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, + NR_ICMP_TYPES + 1)].error) nf_ct_attach(skb, icmp_param->skb); return 0; } -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing bounds check on ICMP reply type before indexing into icmp_pointers[] array, allowing out-of-bounds read when processing extended echo replies (ICMP_EXT_ECHOREPLY)."
Attack vector
An attacker can send a crafted ICMP packet that triggers an extended echo reply (ICMP_EXT_ECHOREPLY) from the kernel. The reply type value is outside the range covered by icmp_pointers[] (which only describes traditional ICMP types up to NR_ICMP_TYPES). When icmp_glue_bits() in net/ipv4/icmp.c uses the reply type as an index into icmp_pointers[] without a bounds check, it performs an out-of-bounds array read [patch_id=2660241]. This can lead to a kernel crash or potentially information disclosure depending on what memory follows the array.
Affected code
The vulnerable code is in the icmp_glue_bits() function in net/ipv4/icmp.c. The original line `if (icmp_pointers[icmp_param->data.icmph.type].error)` directly indexes the icmp_pointers[] array using the ICMP type from the reply parameters without any bounds validation [patch_id=2660241].
What the fix does
The patch adds a bounds check before the icmp_pointers[] lookup in icmp_glue_bits() [patch_id=2660241]. It first verifies that icmp_param->data.icmph.type is less than or equal to NR_ICMP_TYPES, and only then performs the indexed access using array_index_nospec() to prevent speculative out-of-bounds reads. The <linux/nospec.h> header is also included to provide the array_index_nospec() barrier. This ensures that reply types outside the traditional ICMP type range (such as ICMP_EXT_ECHOREPLY) are safely handled without accessing invalid memory, while normal ICMP replies retain their existing behavior.
Preconditions
- networkThe attacker must be able to send network packets to the target host that trigger an ICMP extended echo reply (ICMP_EXT_ECHOREPLY).
- authNo authentication is required; the vulnerability is reachable from unprivileged network access.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/67bf002a2d7387a6312138210d0bd06e3cf4879bnvd
- git.kernel.org/stable/c/92e7c209036dcc0e8ffdf806fdfd3645b263bea5nvd
- git.kernel.org/stable/c/bc64a66e0b9ad937d3d49934242ee62b01ba9a94nvd
- git.kernel.org/stable/c/c2178ff1c70ebfc2ab9651b230c58a34683db759nvd
- git.kernel.org/stable/c/d700c34a5d186b9ba0715bcb19e0ff80ffbfbfc1nvd
News mentions
0No linked articles in our index yet.