---
id: CVE-2026-99191
title: 'calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()'
summary: "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…"
severity: none
vendor: Linux
product: Linux
affected:
  - >-
    Linux >= 81fbc812132cbc72a0f933b19bfd3a829bd946e4 <
    1c9fcfca51e3c5cd46dd72a4da74d56eff183513
  - >-
    Linux >= 81fbc812132cbc72a0f933b19bfd3a829bd946e4 <
    8ee0e03663826a76507048d58466b29321a57656
  - >-
    Linux >= 81fbc812132cbc72a0f933b19bfd3a829bd946e4 <
    8070ed578b6b9134e045627fb745c887a806d46e
  - Linux 5.19
published: '2026-10-28'
updated: '2026-10-28'
sourceUpdated: '2026-10-28T10:35:47.854Z'
source: CVEORG
sourceUrl: 'https://www.cve.org/CVERecord?id=CVE-2026-99191'
references:
  - url: 'https://git.kernel.org/stable/c/1c9fcfca51e3c5cd46dd72a4da74d56eff183513'
  - url: 'https://git.kernel.org/stable/c/8ee0e03663826a76507048d58466b29321a57656'
  - url: 'https://git.kernel.org/stable/c/8070ed578b6b9134e045627fb745c887a806d46e'
tags:
  - cve.org
ingestedAt: '2026-10-28T11:09:40.375Z'
---

## Overview

In the Linux kernel, the following vulnerability has been resolved:

calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()

calipso_skbuff_setattr() adjusts payload_len by the length of the
option it inserts or resizes:

	payload = ntohs(ip6_hdr->payload_len);
	ip6_hdr->payload_len = htons(payload + len_delta);

GRO can build BIG TCP packets larger than IPV6_MAXPLEN, and stores
payload_len == 0 for them; ipv6_payload_len() then falls back to
skb->len.  For such a packet forwarded to a destination mapped to
CALIPSO, the code above writes len_delta (or 65536 + len_delta when
shrinking) into payload_len, and ipv6_payload_len() no longer falls
back to skb->len.  nf_tables, conntrack and sch_cake rely on it.

The same arithmetic also wraps when a packet grows past IPV6_MAXPLEN,
and a BIG TCP packet that shrinks below IPV6_MAXPLEN should get its
real length back.

Set payload_len from the skb length with ipv6_set_payload_len(), which
stores 0 above IPV6_MAXPLEN and the real length otherwise, as
ipv6_gro_complete() does.  The network header was just reset to
skb->data, so skb->len - sizeof(*ip6_hdr) is the payload length.

Tested on one kernel (arm64, QEMU) with SELinux permissive, a minimal
mdp-generated policy (network_peer_controls=1), "netlabelctl calipso
add pass doi:16" and a NetLabel mapping of fd00:2::/64 to CALIPSO
DOI 16.  calipso_skbuff_setattr() was called through
netlbl_skbuff_setattr() from a test-only debugfs hook (not part of
this patch) adding a level-only label; payload_len after the call:

  case                         before fix   after fix   real length
  1000, unlabeled                    1016        1016          1016
  70000 GSO, payload_len 0             16           0         70016
  65530 GSO, grows past MAXPLEN        10           0         65546
  65540 GSO with a 24 byte hop
  header, shrinks below MAXPLEN     65528       65532         65532
  1000 with a 24 byte hop header      992         992           992

(0 means ipv6_payload_len() returns the real length.)  On the forward
path, with a client injecting unlabeled UDP through a router to a
server, the router adds the CALIPSO option and the server delivers all
datagrams (Udp6InDatagrams 5, Ip6InTruncatedPkts 0) with this patch.

## Affected

- `Linux >= 81fbc812132cbc72a0f933b19bfd3a829bd946e4 < 1c9fcfca51e3c5cd46dd72a4da74d56eff183513`
- `Linux >= 81fbc812132cbc72a0f933b19bfd3a829bd946e4 < 8ee0e03663826a76507048d58466b29321a57656`
- `Linux >= 81fbc812132cbc72a0f933b19bfd3a829bd946e4 < 8070ed578b6b9134e045627fb745c887a806d46e`
- `Linux 5.19`

## Remediation

Refer to the linked advisories for vendor-supplied fixes and affected version ranges.
