{"api_version":"1","generated_at":"2026-10-31T15:47:01+00:00","cve":"CVE-2026-99191","urls":{"html":"https://cve.report/CVE-2026-99191","api":"https://cve.report/api/cve/CVE-2026-99191.json","docs":"https://cve.report/api","cve_org":"https://www.cve.org/CVERecord?id=CVE-2026-99191","nvd":"https://nvd.nist.gov/vuln/detail/CVE-2026-99191"},"summary":{"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.","state":"PUBLISHED","assigner":"Linux","published_at":"2026-10-28 11:17:40","updated_at":"2026-10-30 13:21:52"},"problem_types":[],"metrics":[],"references":[{"url":"https://git.kernel.org/stable/c/929dc8e2c9165bb651dca26b2c68067a3880406b","name":"https://git.kernel.org/stable/c/929dc8e2c9165bb651dca26b2c68067a3880406b","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/1c9fcfca51e3c5cd46dd72a4da74d56eff183513","name":"https://git.kernel.org/stable/c/1c9fcfca51e3c5cd46dd72a4da74d56eff183513","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/e29d0a00c619ac794b05d64f4438204478137365","name":"https://git.kernel.org/stable/c/e29d0a00c619ac794b05d64f4438204478137365","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/8ee0e03663826a76507048d58466b29321a57656","name":"https://git.kernel.org/stable/c/8ee0e03663826a76507048d58466b29321a57656","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/8070ed578b6b9134e045627fb745c887a806d46e","name":"https://git.kernel.org/stable/c/8070ed578b6b9134e045627fb745c887a806d46e","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-99191","name":"CVE Program record","refsource":"CVE.ORG","tags":["canonical"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-99191","name":"NVD vulnerability detail","refsource":"NVD","tags":["canonical","analysis"]}],"affected":[{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 81fbc812132cbc72a0f933b19bfd3a829bd946e4 e29d0a00c619ac794b05d64f4438204478137365 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 81fbc812132cbc72a0f933b19bfd3a829bd946e4 929dc8e2c9165bb651dca26b2c68067a3880406b git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 81fbc812132cbc72a0f933b19bfd3a829bd946e4 1c9fcfca51e3c5cd46dd72a4da74d56eff183513 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 81fbc812132cbc72a0f933b19bfd3a829bd946e4 8ee0e03663826a76507048d58466b29321a57656 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 81fbc812132cbc72a0f933b19bfd3a829bd946e4 8070ed578b6b9134e045627fb745c887a806d46e git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 5.19","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 5.19 semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.6.161 6.6.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.12.115 6.12.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.18.59 6.18.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.2.13 7.2.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.3 * original_commit_for_fix","platforms":[]}],"timeline":[],"solutions":[],"workarounds":[],"exploits":[],"credits":[],"nvd_cpes":[],"vendor_comments":[],"enrichments":{"kev":null,"epss":{"cve_year":"2026","cve_id":"99191","cve":"CVE-2026-99191","epss":"0.001720000","percentile":"0.066420000","score_date":"2026-10-30","updated_at":"2026-10-31 00:01:13"},"legacy_qids":[]},"source_records":{"cve_program":{"containers":{"cna":{"affected":[{"defaultStatus":"unaffected","product":"Linux","programFiles":["net/ipv6/calipso.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"lessThan":"e29d0a00c619ac794b05d64f4438204478137365","status":"affected","version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","versionType":"git"},{"lessThan":"929dc8e2c9165bb651dca26b2c68067a3880406b","status":"affected","version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","versionType":"git"},{"lessThan":"1c9fcfca51e3c5cd46dd72a4da74d56eff183513","status":"affected","version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","versionType":"git"},{"lessThan":"8ee0e03663826a76507048d58466b29321a57656","status":"affected","version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","versionType":"git"},{"lessThan":"8070ed578b6b9134e045627fb745c887a806d46e","status":"affected","version":"81fbc812132cbc72a0f933b19bfd3a829bd946e4","versionType":"git"}]},{"defaultStatus":"affected","product":"Linux","programFiles":["net/ipv6/calipso.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"status":"affected","version":"5.19"},{"lessThan":"5.19","status":"unaffected","version":"0","versionType":"semver"},{"lessThanOrEqual":"6.6.*","status":"unaffected","version":"6.6.161","versionType":"semver"},{"lessThanOrEqual":"6.12.*","status":"unaffected","version":"6.12.115","versionType":"semver"},{"lessThanOrEqual":"6.18.*","status":"unaffected","version":"6.18.59","versionType":"semver"},{"lessThanOrEqual":"7.2.*","status":"unaffected","version":"7.2.13","versionType":"semver"},{"lessThanOrEqual":"*","status":"unaffected","version":"7.3","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"cpeMatch":[{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.6.161","versionStartIncluding":"5.19","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.12.115","versionStartIncluding":"5.19","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.18.59","versionStartIncluding":"5.19","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.2.13","versionStartIncluding":"5.19","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.3","versionStartIncluding":"5.19","vulnerable":true}],"negate":false,"operator":"OR"}]}],"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."}],"providerMetadata":{"dateUpdated":"2026-10-30T12:42:48.993Z","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux"},"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"}],"title":"calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()","x_generator":{"engine":"bippy-1.2.0"}}},"cveMetadata":{"assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","assignerShortName":"Linux","cveId":"CVE-2026-99191","datePublished":"2026-10-28T10:35:47.854Z","dateReserved":"2026-09-25T10:25:14.400Z","dateUpdated":"2026-10-30T12:42:48.993Z","state":"PUBLISHED"},"dataType":"CVE_RECORD","dataVersion":"5.2"},"nvd":{"publishedDate":"2026-10-28 11:17:40","lastModifiedDate":"2026-10-30 13:21:52","problem_types":[],"metrics":[],"configurations":[]},"legacy_mitre":{"record":{"CveYear":"2026","CveId":"99191","Ordinal":"1","Title":"calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()","CVE":"CVE-2026-99191","Year":"2026"},"notes":[{"CveYear":"2026","CveId":"99191","Ordinal":"1","NoteData":"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.","Type":"Description","Title":"calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()"}]}}}