{"id":"CVE-2026-99191","state":"PUBLISHED","title":"calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()","description":"In the Linux kernel, the following vulnerability has been resolved:\n\ncalipso: keep BIG TCP payload_len in calipso_skbuff_setattr()\n\ncalipso_skbuff_setattr() adjusts payload_len by the length of the\noption it inserts or resizes:\n\n\tpayload = ntohs(ip6_hdr->payload_len);\n\tip6_hdr->payload_len = htons(payload + len_delta);\n\nGRO can build BIG TCP packets larger than IPV6_MAXPLEN, and stores\npayload_len == 0 for them; ipv6_payload_len() then falls back to\nskb->len.  For such a packet forwarded to a destination mapped to\nCALIPSO, the code above writes len_delta (or 65536 + len_delta when\nshrinking) into payload_len, and ipv6_payload_len() no longer falls\nback to skb->len.  nf_tables, conntrack and sch_cake rely on it.\n\nThe same arithmetic also wraps when a packet grows past IPV6_MAXPLEN,\nand a BIG TCP packet that shrinks below IPV6_MAXPLEN should get its\nreal length back.\n\nSet payload_len from the skb length with ipv6_set_payload_len(), which\nstores 0 above IPV6_MAXPLEN and the real length otherwise, as\nipv6_gro_complete() does.  The network header was just reset to\nskb->data, so skb->len - sizeof(*ip6_hdr) is the payload length.\n\nTested on one kernel (arm64, QEMU) with SELinux permissive, a minimal\nmdp-generated policy (network_peer_controls=1), \"netlabelctl calipso\nadd pass doi:16\" and a NetLabel mapping of fd00:2::/64 to CALIPSO\nDOI 16.  calipso_skbuff_setattr() was called through\nnetlbl_skbuff_setattr() from a test-only debugfs hook (not part of\nthis patch) adding a level-only label; payload_len after the call:\n\n  case                         before fix   after fix   real length\n  1000, unlabeled                    1016        1016          1016\n  70000 GSO, payload_len 0             16           0         70016\n  65530 GSO, grows past MAXPLEN        10           0         65546\n  65540 GSO with a 24 byte hop\n  header, shrinks below MAXPLEN     65528       65532         65532\n  1000 with a 24 byte hop header      992         992           992\n\n(0 means ipv6_payload_len() returns the real length.)  On the forward\npath, with a client injecting unlabeled UDP through a router to a\nserver, the router adds the CALIPSO option and the server delivers all\ndatagrams (Udp6InDatagrams 5, Ip6InTruncatedPkts 0) with this patch.","publishedAt":"2026-10-28T10:35:47.854Z","updatedAt":"2026-10-30T12:42:48.993Z","severity":null,"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"e29d0a00c619ac794b05d64f4438204478137365","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"929dc8e2c9165bb651dca26b2c68067a3880406b","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"1c9fcfca51e3c5cd46dd72a4da74d56eff183513","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"8ee0e03663826a76507048d58466b29321a57656","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"8070ed578b6b9134e045627fb745c887a806d46e","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/ipv6/calipso.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"5.19","status":"affected"},{"version":"0","status":"unaffected","lessThan":"5.19","versionType":"semver"},{"version":"6.6.161","status":"unaffected","lessThanOrEqual":"6.6.*","versionType":"semver"},{"version":"6.12.115","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.59","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.13","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/ipv6/calipso.c"]}],"references":["https://git.kernel.org/stable/c/e29d0a00c619ac794b05d64f4438204478137365","https://git.kernel.org/stable/c/929dc8e2c9165bb651dca26b2c68067a3880406b","https://git.kernel.org/stable/c/1c9fcfca51e3c5cd46dd72a4da74d56eff183513","https://git.kernel.org/stable/c/8ee0e03663826a76507048d58466b29321a57656","https://git.kernel.org/stable/c/8070ed578b6b9134e045627fb745c887a806d46e"],"weaknesses":[],"ingestedAt":"2026-10-30T13:02:04.640Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/99xxx/CVE-2026-99191.json","commit":"cb14bf1b43b0c9f05f7f40eae2246263fd430780","baselineCommit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-99191","state":"PUBLISHED","datePublished":"2026-10-28T10:35:47.854Z","dateUpdated":"2026-10-30T12:42:48.993Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2026-09-25T10:25:14.400Z"},"containers":{"cna":{"title":"calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\ncalipso: keep BIG TCP payload_len in calipso_skbuff_setattr()\n\ncalipso_skbuff_setattr() adjusts payload_len by the length of the\noption it inserts or resizes:\n\n\tpayload = ntohs(ip6_hdr->payload_len);\n\tip6_hdr->payload_len = htons(payload + len_delta);\n\nGRO can build BIG TCP packets larger than IPV6_MAXPLEN, and stores\npayload_len == 0 for them; ipv6_payload_len() then falls back to\nskb->len.  For such a packet forwarded to a destination mapped to\nCALIPSO, the code above writes len_delta (or 65536 + len_delta when\nshrinking) into payload_len, and ipv6_payload_len() no longer falls\nback to skb->len.  nf_tables, conntrack and sch_cake rely on it.\n\nThe same arithmetic also wraps when a packet grows past IPV6_MAXPLEN,\nand a BIG TCP packet that shrinks below IPV6_MAXPLEN should get its\nreal length back.\n\nSet payload_len from the skb length with ipv6_set_payload_len(), which\nstores 0 above IPV6_MAXPLEN and the real length otherwise, as\nipv6_gro_complete() does.  The network header was just reset to\nskb->data, so skb->len - sizeof(*ip6_hdr) is the payload length.\n\nTested on one kernel (arm64, QEMU) with SELinux permissive, a minimal\nmdp-generated policy (network_peer_controls=1), \"netlabelctl calipso\nadd pass doi:16\" and a NetLabel mapping of fd00:2::/64 to CALIPSO\nDOI 16.  calipso_skbuff_setattr() was called through\nnetlbl_skbuff_setattr() from a test-only debugfs hook (not part of\nthis patch) adding a level-only label; payload_len after the call:\n\n  case                         before fix   after fix   real length\n  1000, unlabeled                    1016        1016          1016\n  70000 GSO, payload_len 0             16           0         70016\n  65530 GSO, grows past MAXPLEN        10           0         65546\n  65540 GSO with a 24 byte hop\n  header, shrinks below MAXPLEN     65528       65532         65532\n  1000 with a 24 byte hop header      992         992           992\n\n(0 means ipv6_payload_len() returns the real length.)  On the forward\npath, with a client injecting unlabeled UDP through a router to a\nserver, the router adds the CALIPSO option and the server delivers all\ndatagrams (Udp6InDatagrams 5, Ip6InTruncatedPkts 0) with this patch."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"e29d0a00c619ac794b05d64f4438204478137365","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"929dc8e2c9165bb651dca26b2c68067a3880406b","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"1c9fcfca51e3c5cd46dd72a4da74d56eff183513","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"8ee0e03663826a76507048d58466b29321a57656","versionType":"git"},{"version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","status":"affected","lessThan":"8070ed578b6b9134e045627fb745c887a806d46e","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/ipv6/calipso.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"5.19","status":"affected"},{"version":"0","status":"unaffected","lessThan":"5.19","versionType":"semver"},{"version":"6.6.161","status":"unaffected","lessThanOrEqual":"6.6.*","versionType":"semver"},{"version":"6.12.115","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.59","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.13","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/ipv6/calipso.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/e29d0a00c619ac794b05d64f4438204478137365"},{"url":"https://git.kernel.org/stable/c/929dc8e2c9165bb651dca26b2c68067a3880406b"},{"url":"https://git.kernel.org/stable/c/1c9fcfca51e3c5cd46dd72a4da74d56eff183513"},{"url":"https://git.kernel.org/stable/c/8ee0e03663826a76507048d58466b29321a57656"},{"url":"https://git.kernel.org/stable/c/8070ed578b6b9134e045627fb745c887a806d46e"}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-10-30T12:42:48.993Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.19","versionEndExcluding":"6.6.161"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.19","versionEndExcluding":"6.12.115"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.19","versionEndExcluding":"6.18.59"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.19","versionEndExcluding":"7.2.13"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.19","versionEndExcluding":"7.3"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}}}}}