### Root Cause Analysis
#### 1. Overview of the Bug
The reported bug is a permanent kernel memory leak of an `sk_buff` (size 240) and its attached `sec_path` extension `skb_ext` (size 192). The leak occurs in the IP-TFS (IP Traffic Flow Security, `XFRM_MODE_IPTFS`) encapsulation logic in `net/xfrm/xfrm_iptfs.c`.
#### 2. Detailed Technical Walkthrough
1. **Packet Ingestion and Tunnel / ESP Processing**:
An ESP packet received via a TUN interface is passed up through `tun_get_user()` -> `netif_receive_skb()` -> `ip_rcv()` -> `ip_protocol_deliver_rcu()` -> `xfrm4_esp_rcv()`. The VTI ESP protocol handler (`vti_rcv_proto()` / `vti_input()`) looks up the tunnel and invokes `xfrm_input(skb, nexthdr, spi, encap_type)`.
2. **XFRM Processing & IPTFS Handoff**:
In `net/xfrm/xfrm_input.c:xfrm_input()`, a security path extension is allocated and attached to the skb via `secpath_set(skb)` at line 571 (the second leaked object, size 192).
After ESP payload decryption (`esp_input()`), `xfrm_input()` calls `xfrm_inner_mode_input(x, skb)`. Because the SA mode is configured as `XFRM_MODE_IPTFS` (mode 5), it executes `iptfs_input()` (`
net/xfrm/xfrm_iptfs.c:1724`).
`iptfs_input()` takes ownership of the skb and returns `-EINPROGRESS`, which causes `xfrm_input()` to return `0` without freeing or dropping the skb.
3. **Packet Reassembly and Payload Processing**:
`iptfs_input()` orders the incoming packet and calls `iptfs_input_ordered(x, skb)` (`
net/xfrm/xfrm_iptfs.c:1225`).
`iptfs_input_ordered()` initializes a local list on its stack frame (`struct list_head sublist; INIT_LIST_HEAD(&sublist);`) and calls `__input_process_payload(x, data, &skbseq, &sublist)`.
4. **The Root Cause Defect in `__input_process_payload()`**:
Inside `__input_process_payload()` (`
net/xfrm/xfrm_iptfs.c:950`):
- In the while loop (`while (data < tail)`), the received linear `skb` is reused for the first inner packet (lines 1066–1094):
`first_skb = skb;`
`defer = NULL;`
- The packet is prepared and added to the list of packets to be forwarded:
`iptfs_complete_inner_skb(x, skb);`
`list_add_tail(&skb->list, sublist);` (line 1178)
- When the loop continues to evaluate the subsequent data block (such as trailing payload bytes, malformed padding, or subsequent inner packet headers), if an error occurs (such as `skb_copy_seq_read()` failure, invalid inner IP version `iph->version` not in {0, 4, 6}, or invalid header/packet length `iplen < iphlen`):
```c
} else {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
goto done;
}
```
Execution immediately jumps to `done:` (line 1201), skipping the packet transmission loop at line 1196 (`list_for_each_entry_safe(skb, next, sublist, list)`).
- At label `done:`, cleanup logic only handles `defer` or `!first_skb`:
```c
done:
skb = skbseq->root_skb;
skb_abort_seq_read(skbseq);
if (defer) {
consume_skb(defer);
} else if (!first_skb) {
kfree_skb(skb);
}
return true;
```
Because `first_skb` was set to `skb` and `defer` is `NULL`, neither branch is taken!
Furthermore, `sublist` is never walked or drained. Any packets queued onto `sublist` (including `first_skb` and any reassembled packets added earlier by `iptfs_reassem_cont()`) remain linked in `sublist`.
- `__input_process_payload()` returns `true`. In `iptfs_input_ordered()`, `consumed` is `true`, so `if (!consumed)` at line 1297 is not taken.
- `iptfs_input_ordered()` returns, destroying the stack frame holding `sublist`. The hex dump in the leak report confirms this: `skb->next` and `skb->prev` contain `0xffffc900021f3890`, which is the exact address of `sublist` on the kernel thread stack.
### Classification and Impact
- **RootCauseFiles**: `net/xfrm/xfrm_iptfs.c` contains the missing cleanup in `__input_process_payload()`.
- **MemoryCorruption**: `false`. The unreferenced `sk_buff` and `sec_path` objects are orphaned on the heap without any surviving dangling pointers reachable by subsequent kernel operations; no invalid write, invalid free, or use-after-free occurs.
- **InfoLeak**: `none`. The defect only leaks memory allocation slots, disclosing no kernel data to user space.
- **RawDenialOfService**: `true`. Each malformed or unaligned IP-TFS packet causes permanent kernel heap exhaustion of `sk_buff` and `skb_ext` slab caches, eventually causing an out-of-memory denial of service.
- **IsNetCandidate**: `true`. The bug is located in the XFRM IPsec networking subsystem and IP-TFS protocol processing.
- **IsKVMCandidate**: `false`. The issue is unrelated to KVM or virtualization.