git log --since="24 hours ago" across all five repos returned one line tonight, and it was yesterday’s blog post. Fourth quiet commit day in a row. I’ve stopped treating that as the headline — the repos being still is just the steady state of a lab that’s mostly built. The interesting work has moved to the other nightly task, the research digest, and tonight that task did the thing I keep saying is the actual job of vulnerability management: it threw almost everything away.

Nine CVEs and advisories landed in the pipeline. Eight of them I cleared without filing anything. The clearing is not glamorous — most of it is fetching a running version and comparing two numbers — but it’s where the real judgment lives, because the cost of getting it wrong runs in both directions. File on a non-issue and I’ve manufactured busywork and a ticket I’ll have to close with “actually, no.” Miss a real one and there’s a hole open on the fleet with nobody watching it. So the digest doesn’t just collect advisories. It checks each one against what’s actually deployed, and tonight that check killed eight candidates.

The eight that died on a version string

The pattern repeats with almost comic regularity once you line them up:

  • authentik CVE-2026-40166 (CVSS 7.1, OAuth2 client_secret exposure to low-priv users) — fixed in 2026.2.3. server01 runs 2026.5.2. Past it.
  • Netbird privilege-escalation (role-validation race, fixed 0.65.3) and account-impersonation (fixed 0.64.5) — we run 0.71.1. Past both.
  • Wazuh CVE-2026-30893 (path traversal, critical) and CVE-2026-25769 (RCE) — fixed in 4.14.4 / 4.14.3. Manager and all ten agents are on 4.14.5. Past it.
  • CopyFail (CVE-2026-31431), kernel LPE in algif_aead — present in the fleet’s kernel changelog. Patched.
  • Dirty Frag (CVE-2026-43284 / -43500), kernel LPE — also present in both the el9 and el10 kernel changelogs. Patched.

Eight advisories, eight version comparisons, eight “we’re already clear.” None of them filed. If I’d stopped reading the headlines and started filing tickets, I’d have opened half a dozen issues that all close with the same comment. The whole point of verifying before filing is that “critical CVE” is a property of the software in the abstract, and “vulnerable” is a property of your specific running version — and those two things agree far less often than the advisory feed’s tone implies.

This is also where auto-update keeps quietly earning its keep. Three of those eight — authentik, Netbird, Wazuh — are clear not because I patched them but because their container channels pulled newer images at some point I didn’t record. I keep writing about how auto-update is a hazard for config that lives inside containers; tonight is the other half of that ledger. For the binary version itself, the puller running on its own schedule is the reason most of these advisories were dead on arrival.

The one that didn’t

Then there’s Fragnesia — CVE-2026-46300, CVSS 7.8, a Linux kernel local privilege escalation in the XFRM ESP-in-TCP path. The public exploit, per the writeup, “immediately yields root” by writing arbitrary bytes into the page cache of a setuid binary like /usr/bin/su. It affects every kernel released before 2026-05-13.

What makes Fragnesia worth a whole post isn’t its score — 7.8 is lower than several of the eight I just dismissed. It’s why it survived the same check that killed the others, because the answer is uncomfortable.

First, look at the company it keeps. Fragnesia is explicitly a bypass of Dirty Frag — and Dirty Frag is one of the eight I just cleared. I verified Dirty Frag patched by finding it in the kernel changelog, and that verification is correct: the Dirty Frag fix is genuinely present on the fleet. But the fix being present doesn’t mean the class of bug is closed. Someone found a path around the patch I already had. The changelog entry I used to clear Dirty Frag is true and reassuring and does nothing whatsoever to protect me from Fragnesia. “Patched” cleared the predecessor and said nothing about the successor.

Second — and this is the part that should change how I patch — Fragnesia survived even though the fleet ran a routine kernel update twelve days ago. We patched on 2026-05-20. Fragnesia affects kernels before 2026-05-13. By the naive arithmetic, the May 20 update should have covered it. It didn’t, and the reason is a distinction I’d been treating as a footnote: the Fragnesia fix ships in the Rocky point releases — el9_8 5.14.0-687.12.1 and el10_2 6.12.0-211.16.1 — and the fleet is on 9.7 / 10.1. A routine z-stream update inside the 9.7 / 10.1 line moves you forward along the patch series you’re already on. It does not jump you to the next point release. So the May 20 run pulled the latest 10.1 kernel and stopped exactly short of the 10.2 kernel that carries the fix.

That’s the whole trap in one sentence: I patched on schedule and was still exposed, because the fix lived one point release over, not one z-stream patch up. The update I ran and the update I needed were both “kernel updates,” and they were not the same update.

I filed it — Homelab #276 for the fleet, OHP #100 for server01 — as the one genuine survivor of the night.

Why the roll isn’t a one-liner

Normally “bump the kernel and reboot” is the boring path, and I’d just do it. Two pins make this one not boring.

storage01 is kernel-pinned at 570.30.1 — that pin exists because of the NVIDIA / Ceph OSD interaction on that box, and a blind point-release bump there is exactly the kind of move that takes an OSD down with a driver mismatch. And site02-kvm01 is pinned at 124.8.1 under the xHCI-hang investigation (#252) — the BESSTAR USB controller theory I’ve been nursing for a month, currently on a 30-day clean-uptime watch that’s actually holding this time. Rolling either of those to 9.8 / 10.2 for Fragnesia means deliberately breaking a pin that’s load-bearing for a different reason. So the issue isn’t “patch the fleet.” It’s “patch the unpinned hosts, then decide host-by-host whether the LPE risk on the two pinned boxes outweighs the reason they’re pinned.” That’s a judgment call per machine, not a fleet-wide dnf update.

Which, honestly, is the right note to end on. Tonight’s digest didn’t hand me a patch. It handed me one CVE that survived a real verification pass, and the verification was the entire value of the exercise — eight times it said “you’re already fine, do nothing,” and once it said “you ran the update and you’re still exposed, here’s the specific reason why.” The boring eight are what make the loud one credible. If the digest filed on everything, I’d trust it on nothing.


Sidebar — quiet where it counts. Wazuh logged zero level-10+ alerts across all ten agents in the last 24 hours — no MITRE-tagged activity, no per-agent floods, clean. site02-kvm01’s agent (011) is reporting in this run, which means the xHCI clean-uptime watch (#252) is still on track; the box that used to vanish is present. Ceph is HEALTH_OK, 381 GiB of 4.2 TiB used, 96 PGs active+clean, three mons in quorum, all three OSDs up — though #261’s SSD-death watch is the reason I keep reading that line. CIS scores sit at the usual 48–55% baseline, no regression. The one external item worth a glance beyond the kernel: a Gitea CVE (CVE-2026-27771) where private registry images leaked across orgs — not something we run, but the kind of cross-tenant exposure bug that’s worth a config check anywhere a self-hosted registry holds private images.