{"id":"CVE-2026-98372","state":"PUBLISHED","title":"xfrm: iptfs: fix stack OOB read in iptfs_skb_reset_frag_walk()","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nxfrm: iptfs: fix stack OOB read in iptfs_skb_reset_frag_walk()\n\niptfs_skb_reset_frag_walk() advances to the fragment containing @offset\nwith an unbounded loop:\n\n\twhile (offset >= walk->past + walk->frags[walk->fragi].len)\n\t\twalk->past += walk->frags[walk->fragi++].len;\n\nwalk->fragi is advanced and walk->frags[walk->fragi] is dereferenced\nwithout ever checking fragi against walk->nr_frags. When the requested\noffset is at or beyond the total length spanned by the walk's fragments,\nfragi runs past nr_frags and off the end of the fixed-size on-stack\nfrags[MAX_SKB_FRAGS + 1] array, reading out-of-bounds stack memory.\n\nThe two callers behave differently: iptfs_skb_add_frags() already guards\nagainst this with\n\n\tif (!walk->nr_frags ||\n\t    offset >= walk->total + walk->initial_offset)\n\t\treturn len;\n\nbut iptfs_skb_can_add_frags() has no such guard and calls\niptfs_skb_reset_frag_walk() unconditionally, so it performs the\nout-of-range walk. Its own \"fragi < walk->nr_frags\" bound check runs only\nafterwards, too late to prevent the read.\n\nThis is reachable from the receive path: a crafted IP-TFS (AGGFRAG)\npayload delivered to an IPTFS SA drives iptfs_reassem_cont() ->\niptfs_skb_can_add_frags() with an offset past the fragment total, e.g.:\n\n  BUG: KASAN: stack-out-of-bounds in iptfs_skb_reset_frag_walk+0x235/0x250\n  Read of size 4 at addr ffff888008ad7210 by task repro/345\n   iptfs_skb_reset_frag_walk+0x235/0x250 net/xfrm/xfrm_iptfs.c:392\n   iptfs_skb_can_add_frags+0x155/0x310  net/xfrm/xfrm_iptfs.c:420\n   iptfs_reassem_cont+0xcf8/0x1140      net/xfrm/xfrm_iptfs.c:902\n   iptfs_input_ordered+0x552/0x670      net/xfrm/xfrm_iptfs.c:1280\n   iptfs_input+0x3d6/0xde0              net/xfrm/xfrm_iptfs.c:1741\n   xfrm_input+0x282f/0x6140             net/xfrm/xfrm_input.c:700\n   xfrm4_esp_rcv+0x93/0x120             net/ipv4/xfrm4_protocol.c:104\n   ip_rcv+0x278/0x2d0                   net/ipv4/ip_input.c:612\n\nGive iptfs_skb_can_add_frags() the same up-front guard that\niptfs_skb_add_frags() already has, so the walk is never entered with an\nout-of-range offset. When it triggers, the caller falls back to the\nexisting linearize-and-copy path, which is safe.","publishedAt":"2026-10-06T08:46:56.529Z","updatedAt":"2026-10-19T09:18:24.195Z","severity":null,"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"5f2b6a9095743a6bf1f34c43c4fe78fa8bdf5ad7","status":"affected","lessThan":"7e1c6884a0b494b7e3f204877f94c1e07a117bf7","versionType":"git"},{"version":"5f2b6a9095743a6bf1f34c43c4fe78fa8bdf5ad7","status":"affected","lessThan":"da56d0ee93d1bad779b0486f2fab92d1bc1f0cf3","versionType":"git"},{"version":"5f2b6a9095743a6bf1f34c43c4fe78fa8bdf5ad7","status":"affected","lessThan":"d042487dc118e494db2e2c1382310255c90ff544","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/xfrm/xfrm_iptfs.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.14","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.14","versionType":"semver"},{"version":"6.18.54","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.8","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/xfrm/xfrm_iptfs.c"]}],"references":["https://git.kernel.org/stable/c/7e1c6884a0b494b7e3f204877f94c1e07a117bf7","https://git.kernel.org/stable/c/da56d0ee93d1bad779b0486f2fab92d1bc1f0cf3","https://git.kernel.org/stable/c/d042487dc118e494db2e2c1382310255c90ff544"],"weaknesses":[],"ingestedAt":"2026-10-29T20:13:43.249Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/98xxx/CVE-2026-98372.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-98372","state":"PUBLISHED","datePublished":"2026-10-06T08:46:56.529Z","dateUpdated":"2026-10-19T09:18:24.195Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2026-09-25T10:25:14.345Z"},"containers":{"cna":{"title":"xfrm: iptfs: fix stack OOB read in iptfs_skb_reset_frag_walk()","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nxfrm: iptfs: fix stack OOB read in iptfs_skb_reset_frag_walk()\n\niptfs_skb_reset_frag_walk() advances to the fragment containing @offset\nwith an unbounded loop:\n\n\twhile (offset >= walk->past + walk->frags[walk->fragi].len)\n\t\twalk->past += walk->frags[walk->fragi++].len;\n\nwalk->fragi is advanced and walk->frags[walk->fragi] is dereferenced\nwithout ever checking fragi against walk->nr_frags. When the requested\noffset is at or beyond the total length spanned by the walk's fragments,\nfragi runs past nr_frags and off the end of the fixed-size on-stack\nfrags[MAX_SKB_FRAGS + 1] array, reading out-of-bounds stack memory.\n\nThe two callers behave differently: iptfs_skb_add_frags() already guards\nagainst this with\n\n\tif (!walk->nr_frags ||\n\t    offset >= walk->total + walk->initial_offset)\n\t\treturn len;\n\nbut iptfs_skb_can_add_frags() has no such guard and calls\niptfs_skb_reset_frag_walk() unconditionally, so it performs the\nout-of-range walk. Its own \"fragi < walk->nr_frags\" bound check runs only\nafterwards, too late to prevent the read.\n\nThis is reachable from the receive path: a crafted IP-TFS (AGGFRAG)\npayload delivered to an IPTFS SA drives iptfs_reassem_cont() ->\niptfs_skb_can_add_frags() with an offset past the fragment total, e.g.:\n\n  BUG: KASAN: stack-out-of-bounds in iptfs_skb_reset_frag_walk+0x235/0x250\n  Read of size 4 at addr ffff888008ad7210 by task repro/345\n   iptfs_skb_reset_frag_walk+0x235/0x250 net/xfrm/xfrm_iptfs.c:392\n   iptfs_skb_can_add_frags+0x155/0x310  net/xfrm/xfrm_iptfs.c:420\n   iptfs_reassem_cont+0xcf8/0x1140      net/xfrm/xfrm_iptfs.c:902\n   iptfs_input_ordered+0x552/0x670      net/xfrm/xfrm_iptfs.c:1280\n   iptfs_input+0x3d6/0xde0              net/xfrm/xfrm_iptfs.c:1741\n   xfrm_input+0x282f/0x6140             net/xfrm/xfrm_input.c:700\n   xfrm4_esp_rcv+0x93/0x120             net/ipv4/xfrm4_protocol.c:104\n   ip_rcv+0x278/0x2d0                   net/ipv4/ip_input.c:612\n\nGive iptfs_skb_can_add_frags() the same up-front guard that\niptfs_skb_add_frags() already has, so the walk is never entered with an\nout-of-range offset. When it triggers, the caller falls back to the\nexisting linearize-and-copy path, which is safe."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"5f2b6a9095743a6bf1f34c43c4fe78fa8bdf5ad7","status":"affected","lessThan":"7e1c6884a0b494b7e3f204877f94c1e07a117bf7","versionType":"git"},{"version":"5f2b6a9095743a6bf1f34c43c4fe78fa8bdf5ad7","status":"affected","lessThan":"da56d0ee93d1bad779b0486f2fab92d1bc1f0cf3","versionType":"git"},{"version":"5f2b6a9095743a6bf1f34c43c4fe78fa8bdf5ad7","status":"affected","lessThan":"d042487dc118e494db2e2c1382310255c90ff544","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/xfrm/xfrm_iptfs.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.14","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.14","versionType":"semver"},{"version":"6.18.54","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.8","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/xfrm/xfrm_iptfs.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/7e1c6884a0b494b7e3f204877f94c1e07a117bf7"},{"url":"https://git.kernel.org/stable/c/da56d0ee93d1bad779b0486f2fab92d1bc1f0cf3"},{"url":"https://git.kernel.org/stable/c/d042487dc118e494db2e2c1382310255c90ff544"}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-10-19T09:18:24.195Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.14","versionEndExcluding":"6.18.54"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.14","versionEndExcluding":"7.2.8"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.14","versionEndExcluding":"7.3"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}}}}}