Skip to main content
Back to blog
Brian

Your Linux host is patched. Is it actually running the fixed kernel?

Kernel updates can be installed on disk while the host is still booted into the older vulnerable kernel. Here is a practical RHEL-family workflow for checking reboot debt after patching.

Linux HardeningPatch OperationsVulnerability ManagementRHEL

Kernel patching has a way of looking finished before it is actually finished.

The update job ran. The package manager shows newer kernel packages installed. The vulnerability queue may look better after the next scan. Everyone wants to move on.

But the host only runs one kernel at a time.

Installing a fixed kernel package does not change the kernel already loaded into memory. Until the machine reboots into the fixed kernel, the live system may still be running the older vulnerable one.

That is the gap I want to check after every Linux patch window:

Fixed kernel installed on disk.
But is that fixed kernel actually running?

It sounds basic. It is also one of the easiest places for remediation evidence to get fuzzy.

Kernel packages are different from most package updates

For many userland packages, a service restart may be enough to make the fixed code live. If openssl-libs, glibc, krb5-libs, or another shared library was updated, the remaining question is often which long-running processes still have old code mapped.

Kernel updates are more blunt.

The running kernel is the kernel the host booted. You can install ten newer kernel packages, but uname -r still tells you the one that is currently live.

On a RHEL-family host, the first command is simple:

uname -r

That answers:

What kernel is this host running right now?

It does not answer:

What kernel packages are installed?
What kernel will the host boot next?
Which kernel contains the vendor fix for this CVE?
Did the reboot actually happen after the patch window?

Those are separate questions. Good evidence keeps them separate.

Start with the running kernel

On one host, I usually start with a small identity block:

hostname
date -u +"%Y-%m-%dT%H:%M:%SZ"
cat /etc/os-release
uname -r

That gives you the host label, collection time, distro, and running kernel.

Example shape:

host: app-01
checked_at: 2026-07-23T14:40:12Z
distro: Rocky Linux 9.4
running_kernel: 5.14.0-427.28.1.el9_4.x86_64

The timestamp matters. A reboot check from yesterday is not evidence for today’s remediation state.

Then list the installed kernel packages

For RHEL-family systems, kernel-core is usually the useful package to inspect:

rpm -q kernel-core

If you want install time included:

rpm -q kernel-core --qf '%{INSTALLTIME} %{VERSION}-%{RELEASE}.%{ARCH}\n' | sort -nr

Or the quick human view:

rpm -q --last kernel-core 2>/dev/null

You are looking for a difference between:

running kernel

and:

newer fixed kernel package installed

If a newer fixed kernel is installed but the host is still running an older one, the package update landed but the remediation is not live yet.

That should be called reboot debt, not “done.”

Check what the bootloader plans to use

There is another awkward case: the fixed kernel may be installed, but the host may not be configured to boot it next.

If grubby is available, this is useful:

sudo grubby --default-kernel

You can also list boot entries:

sudo grubby --info=ALL

This is not always needed for a first-pass audit, but it helps when a host keeps rebooting back into an older kernel. Maybe the default boot entry is pinned. Maybe a previous kernel was selected for troubleshooting. Maybe a configuration management rule is preserving a boot choice nobody remembers.

The practical question is:

If this host reboots, will it boot the fixed kernel?

If the answer is no, scheduling a reboot is not enough. The boot target needs review too.

needs-restarting -r is useful evidence

On RHEL-family systems, needs-restarting is a good operator tool when it is available. It commonly comes from the DNF utilities/plugins package for the distro.

For reboot checks:

sudo dnf needs-restarting -r
echo $?

The exact output can vary by distro version and tooling, but the intent is straightforward: detect whether important updated components require a reboot before the host is fully using the updated code.

I would not use it as the only evidence. I like it as one signal next to:

  • uname -r
  • installed kernel-core packages
  • vendor-fixed kernel package/advisory context
  • bootloader default, when needed
  • checked-at timestamp

If those agree, you have a much cleaner story.

The scanner view can be right and still incomplete

This is where vulnerability scanners and Linux operators sometimes talk past each other.

A scanner may report the kernel CVE because it sees the running kernel, installed packages, previous inventory, or a plugin result that has not updated yet.

The Linux team may say the host is patched because dnf update installed the fixed kernel package.

Both sides can be looking at real evidence.

The missing distinction is usually:

Fixed package installed on disk

versus:

Fixed kernel running live

Those are not the same state.

The useful thing is not to argue about whether the scanner is “wrong.” The useful thing is to classify the host accurately.

A practical classification model

For kernel findings, I like these buckets.

Update required

The installed kernel package is below the vendor-fixed version.

status: update required
action: install fixed kernel package

This is not reboot debt yet. The fixed package has not landed.

Reboot required

The vendor-fixed kernel package is installed, but uname -r still shows an older kernel.

status: reboot required
action: reboot into fixed kernel

This is the classic “patched on disk, not live” state.

Boot target review required

The fixed kernel is installed, but the bootloader default still points at an older kernel.

status: boot target review required
action: fix default boot entry before reboot

This avoids the frustrating pattern where a host reboots and comes back still vulnerable.

Verified running fixed kernel

The running kernel matches the vendor-fixed package state.

status: verified running fixed kernel
checked_at: timestamp

This is the closure state you want.

Review required

The data is incomplete, unsupported, or does not line up cleanly.

status: review required
action: inspect package/advisory/boot evidence manually

This is better than pretending the host is clean because the evidence is inconvenient.

What the evidence should look like

For a kernel remediation check, I want a compact record:

Host:
Distro:
Checked at:

CVE / advisory:
Running kernel:
Installed fixed kernel:
Vendor-fixed kernel:
Bootloader default:
needs-restarting result:

Result:
Recommended action:

Example:

Host: app-01
Distro: Rocky Linux 9.4
Checked at: 2026-07-23T14:40:12Z

CVE / advisory: vendor kernel advisory
Running kernel: 5.14.0-427.28.1.el9_4.x86_64
Installed fixed kernel: 5.14.0-427.31.1.el9_4.x86_64
Vendor-fixed kernel: 5.14.0-427.31.1.el9_4.x86_64
Bootloader default: 5.14.0-427.31.1.el9_4.x86_64
needs-restarting result: reboot required

Result: fixed kernel installed, older kernel still running
Recommended action: reboot host during approved window, then verify uname -r

That is much easier to defend than:

Kernel patched.

It shows exactly which part of the work is done and which part remains.

Be careful with shortcuts

There are a few shortcuts that create bad evidence.

Do not assume dnf update means the host is running the fixed kernel.

Do not assume the newest installed kernel is the one currently running.

Do not assume a reboot happened because a maintenance window ended.

Do not assume the host booted into the newest kernel after reboot.

Do not close a kernel vulnerability without a current uname -r or equivalent runtime signal.

None of this is complicated. It is just easy to skip when the patch window is long, the host list is large, and everyone is tired.

The real goal is less ambiguity

Kernel remediation should not be a debate over screenshots, scanner timing, or memory of a reboot window.

The host can tell you what it is running.

The package database can tell you what is installed.

Vendor metadata can tell you what fixed build matters.

The bootloader can tell you what will run after the next reboot.

When those are collected together, the result becomes much clearer:

Update the package.
Reboot the host.
Fix the boot target.
Verified running fixed kernel.
Review required.

That is the difference between patch activity and remediation evidence.

If you want to see this style of evidence in report form, the sample Patch Truth report shows how package state, runtime state, and next action fit together. For one supported RHEL-family host, the one-host snapshot is a quick way to test the flow against a real system.