sp->sw_nblks is a 32-bit int but swaponvp() stores a 64-bit block count — swap devices >= 2^31 pages (8 TiB) truncate to negative/garbage bounds while vm_swap_size still counts the full size
| Field | Value |
|---|---|
| ID | DF-2880 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-197 Integer Overflow or Wraparound |
| File | sys/vm/vm_swap.c |
| Lines | 344, 367 (struct conf.h:181) |
| Area | vm |
| Confidence | certain |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:vm |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
struct swdevt.sw_nblks is int while aligned_nblks is swblk_t=int64_t;
the assignment silently truncates. The :344 guard only bounds nblks by
BLIST_MAXBLKS/nswdev = 2^59 pages — no guard for real hardware. An ≥8TiB
swap device (trivially creatable, incl. sparse NFS file) makes sw_nblks
negative/wrapped: swapdev_strategy then rejects all I/O to the device
while nswap/vm_swap_size/vm_swap_max still count petabytes of
"available" swap — kernel overcommits against a device that can never
take a page, degrading into swap-full/OOM-kill churn; blist_create for
nswap≥2^33 additionally attempts a multi-GB M_WAITOK kmem allocation.
Root-only and ≥8TiB, hence Low; no OOB enabled (truncation only makes
the bound more restrictive). Fix: widen sw_nblks/sw_nused to swblk_t or
reject nblks > INT_MAX pages at registration.
Timeline
- 2026-09-02 Discovered during pass-2 audit of vm_swap.c (GLM 5.3).
No comments yet.