{"id":"CVE-2026-99191","kind":"vulnerability","aliases":["CVE-2026-99191"],"related":[],"title":"Linux kernel: CALIPSO labeling corrupts IPv6 payload length on BIG TCP packets","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.","summary":"The Linux kernel's CALIPSO IPv6 labeling code miscalculates the payload length field when it inserts or resizes a CALIPSO option on BIG TCP (GRO) packets. The wrong length can break packet handling in netfilter, conntrack and the sch_cake scheduler.","severity":"unknown","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["calipso","ipv6","linux-kernel","netlabel","runtime"],"not_affected_if":["no-calipso-configured"],"how_to_check":"- Run `uname -r` and compare against the fixed kernel release in your distribution's advisory\n- Check whether CALIPSO is in use with `netlabelctl calipso list` or by looking for CALIPSO DOI mappings\n- unknown if the sources give further checks","fix":"- Update the Linux kernel to a release that includes the calipso payload_len fix (version unknown from the sources)\n- unknown for any setting change, since the sources do not name one","status":"open","published_at":"2026-10-28T11:17:40+00:00","first_seen_at":"2026-10-28T11:32:37+00:00","triaged_at":"2026-10-28T11:34:13+00:00","updated_at":"2026-10-28T11:34:13+00:00","category":"runtime","confidence":0.5,"triage":{"at":"2026-10-28T11:34:13Z","model":"claude-haiku-5-5","output":{"fix":"- Update the Linux kernel to a release that includes the calipso payload_len fix (version unknown from the sources)\n- unknown for any setting change, since the sources do not name one","reach":"network","title":"Linux kernel: CALIPSO labeling corrupts IPv6 payload length on BIG TCP packets","impact":"low","summary":"The Linux kernel's CALIPSO IPv6 labeling code miscalculates the payload length field when it inserts or resizes a CALIPSO option on BIG TCP (GRO) packets. The wrong length can break packet handling in netfilter, conntrack and the sch_cake scheduler.","category":"runtime","nicknames":[],"who_cares":["linux-kernel","netlabel","calipso","ipv6"],"confidence":0.5,"needs_auth":"unknown","worst_case":"packet lengths corrupted, causing dropped or mishandled traffic on labeled paths","analyst_note":"Sources give no severity, affected kernel versions or fixed release; check the NVD entry and the upstream kernel commit for version ranges.","how_to_check":"- Run `uname -r` and compare against the fixed kernel release in your distribution's advisory\n- Check whether CALIPSO is in use with `netlabelctl calipso list` or by looking for CALIPSO DOI mappings\n- unknown if the sources give further checks","needs_analyst":true,"not_affected_if":["no-calipso-configured"],"who_is_affected":"Only systems that run the Linux kernel with CALIPSO labeling configured through NetLabel, which maps IPv6 destinations to CALIPSO DOI values, can hit this code path. The sources describe a router adding CALIPSO options to forwarded traffic, and packets that GRO has built larger than IPV6_MAXPLEN. Systems that do not use CALIPSO can skip it.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"unknown"},"cost_usd":0.00075,"input_tokens":4133,"output_tokens":674,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'-2026':14A,17A '-99191':15A,18A '/64':296C '0':131C,231C,349C,351C,359C,385C,425C '1':282C '10':358C '1000':340C,375C '1016':342C,343C,344C '16':288C,300C,350C '2':295C '24':365C,378C '5':423C '65528':372C '65530':353C '65532':373C,374C '65536':161C '65540':361C '65546':360C '70000':345C '70016':352C '992':382C,383C,384C 'add':285C,322C,412C 'adjust':90C 'also':192C 'arithmet':191C 'arm64':268C 'back':139C,176C,216C 'big':10A,48B,79C,120C,203C 'break':56B 'build':119C 'byte':366C,379C 'cake':65B,185C 'calipso':3A,19B,30B,45B,77C,84C,87C,153C,284C,298C,301C,414C 'call':305C,332C 'case':333C 'client':400C 'code':33B,155C 'complet':243C 'conntrack':61B,182C 'control':281C 'corrupt':5A 'cve':13A,16A 'data':253C 'datagram':421C 'debugf':315C 'deliv':419C 'delta':116C,159C,163C 'destin':150C 'doi':287C,299C 'fall':138C,175C 'fd00':294C 'field':38B 'fix':335C,337C 'follow':72C 'forward':147C,396C 'generat':277C 'get':212C 'gro':50B,117C,242C 'grow':197C,355C 'gso':346C,354C,362C 'handl':58B 'hdr':106C,110C,259C 'header':247C,368C,381C 'hook':316C 'hop':367C,380C 'hton':113C 'inject':401C 'insert':41B,100C 'ip6':105C,109C,258C 'ip6intruncatedpkts':424C 'ipv6':6A,20B,31B,125C,134C,170C,199C,209C,225C,233C,241C,387C 'keep':78C 'kernel':2A,23B,28B,70C,267C 'label':4A,32B,327C 'larger':123C 'len':82C,92C,108C,112C,115C,130C,136C,142C,158C,162C,168C,172C,179C,219C,228C,256C,329C,348C,389C 'length':8A,37B,54B,95C,215C,223C,238C,263C,339C,393C 'level':325C 'level-on':324C 'linux':1A,22B,27B,69C 'linux-kernel':21B 'longer':174C 'map':151C,292C 'maxplen':126C,200C,210C,234C,357C,371C 'mdp':276C 'mdp-gener':275C 'mean':386C 'minim':274C 'miscalcul':34B 'netfilt':60B 'netlabel':24B,291C 'netlabelctl':283C 'netlbl':307C 'network':246C,279C 'nf':180C 'ntoh':104C 'one':266C 'option':46B,98C,415C 'otherwis':239C 'packet':12A,51B,57B,122C,146C,196C,205C 'part':318C 'pass':286C 'past':198C,356C 'patch':321C,428C 'path':397C 'payload':7A,36B,81C,91C,103C,107C,111C,114C,129C,135C,167C,171C,218C,227C,262C,328C,347C,388C 'peer':280C 'permiss':272C 'polici':278C 'qemu':269C 'real':214C,237C,338C,392C 'reli':186C 'reset':250C 'resiz':43B,102C 'resolv':76C 'return':390C 'router':406C,411C 'runtim':25B 'sch':64B,184C 'schedul':66B 'selinux':271C 'server':409C,418C 'set':217C,226C 'setattr':86C,89C,303C,309C 'shrink':165C,207C,369C 'sizeof':257C 'skb':141C,178C,222C,252C,255C 'skbuff':85C,88C,302C,308C 'store':128C,230C 'tabl':181C 'tcp':11A,49B,80C,121C,204C 'test':264C,313C 'test-on':312C 'udp':403C 'udp6indatagrams':422C 'unlabel':341C,402C 'vulner':73C 'wrap':193C 'write':157C 'wrong':53B","nicknames":[],"mitigations":[],"who_affected":"Only systems that run the Linux kernel with CALIPSO labeling configured through NetLabel, which maps IPv6 destinations to CALIPSO DOI values, can hit this code path. The sources describe a router adding CALIPSO options to forwarded traffic, and packets that GRO has built larger than IPV6_MAXPLEN. Systems that do not use CALIPSO can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-28T11:17:40+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-99191","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-99191","severity":null,"published_at":"2026-10-28T11:17:40+00:00","modified_at":"2026-10-28T11:17:40+00:00","first_seen_at":"2026-10-28T11:32:37+00:00","fetched_at":"2026-10-28T11:32:37+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}