This post is part of a regular series on Oracle Ksplice’s Known Exploit Detection. For selected security vulnerabilities, not only will Ksplice fix the code error, but it will also lay down tripwires to detect exploit attempts.
Known Exploit Detection allows system administrators to report and alarm on future attempts to exploit that vulnerability even after the system has been patched.
Why Exploit Detection Matters
In many cases, a code fix for a security vulnerability is indistinguishable from a bug fix or logic change. Around half of Linux kernel security vulnerabilities are identified retroactively and assigned to patches that are already part of the kernel.
Once the bug is fixed, the program works “correctly” and won’t trigger an alarm if a malicious user tests a known exploit.
For example, the Linux: nf_tables: locking issue in the nf_tables_abort() function lets a local user escalate to root privileges by exploiting a race condition between nftables’ garbage collection thread and the transaction abort path, which results in a double-free of a set element.
When this is fixed, an exploit attempt won’t grant unauthorized access, but the system admin won’t be alerted. With Known Exploit Detection, Ksplice fixes the race condition and sets a tripwire to detect double-free attempts.
Here’s how the warning message for CVE-2024-0193 appears in systemd’s logs when Ksplice detects an attack from the binary a.out
:
Oct 21 01:52:03 localhost.localdomain /log-known-exploit[13821]: exploit attempt detected; id=CVE-2024-0193 pid=13821 uid=0 comm=a.out lost=0
We apply Known Exploit Detection selectively: only for vulnerabilities that are significant and likely to be exploited. Not every patched flaw gets this treatment, it’s reserved for high-profile threats.
Latest Known Exploit Detection Tripwires Added
Here’s a selection of our most recent Known Exploit Detection capabilities in Oracle Ksplice:
-
CVE-2024-26925: This is a race condition between the abort path and the garbage collector (GC) thread, where a set element can be freed by both.
The creation of sets, set elements, objects, rules, chains, etc., is represented by messages (e.g., NFT_MSG_NEWSET, NFT_MSG_NEWSETELEM, etc.). These messages can be sent in a batch, with a commit occurring only after all are successfully processed.
When a user adds an element (using NFT_MSG_NEWSETELEM) with the NFT_SETELEM_TIMEOUT flag to a set, they request that the element expire after a timeout. The garbage collector thread removes expired elements and schedules them for deletion.
The messages to create netfilter objects are stored in
nft_trans
(a transaction data type) and protected bynft_net->commit_mutex
. When a batch is processed, each message is saved innft_trans
and added tonft_net->commit_list
. At the end of the batch,nft_net->commit_mutex
is acquired, andnft_net->commit_list
is processed.If a new object type requires loading a module via
request_module
,nft_net->commit_mutex
is released to avoid long holds. Releasing the mutex breaks the atomicity of the batch, so the transaction is aborted, the mutex is released, the module is loaded, and the transaction is retried.During this abort, the GC thread may wake up. It does not acquire
nft_net->commit_mutex
to avoid ABBA deadlock with application threads. Instead, it adds the expired set elements tagged with the current GC sequence number in a GC transaction to a separate list to be processed for deletion in a work-queue, that can acquirenft_net->commit_mutex
safely.The UAF issue is fixed by ensuring that
nft_net->commit_mutex
is released only after the GC sequence is incremented twice – once before processing the transaction and once after the transaction ends. Since the work-queue acquiresnft_net->commit_mutex
before checking the current GC sequence against the GC sequence in the GC transaction, it fails to match if the application thread has already incremented the current GC sequence number in commit or in abort path, and the work-queue won’t process the elements. -
CVE-2024-0193: This is a Use-After-Free (UAF) in nftables’ chain, referenced from a set element belonging to a
pipapo
set.The UAF occurs when an element in a
pipapo
set expires quickly. Expired elements with CATCHALL flag are added toset->catchall_list
. When a chain is referenced from an element,chain->use
is incremented.NFT_DELCHAIN
does not delete a chain unlesschain->use
is 0.If both a set element and a rule reference the same chain,
chain->use
becomes 2.NFT_DELSET
starts dereferencing set elements and decrementschain->use
of an element if the set element references any chain. Without the fix, NFT_DELSET callspipapo_gc
, which processes the expired elements and decrementschain->use
again andchain->use
incorrectly reaches zero.If
NFT_DELCHAIN
is called afterward, it seeschain->use
is 0 and deletes the chain while a rule still holds a dangling pointer. A malicious user could exploit this to trigger a UAF. -
CVE-2023-4244: This is a Use-After-Free in nftables, similar to CVE-2024-0193, but involving the GC thread.
Here,
NFT_DELSET
decrementschain->use
, and concurrently, the GC thread processesset->catchall_list
for expired set elements and decrements it again and incorrectly causeschain->use
to reach zero.If
NFT_DELCHAIN
is called afterward, it seeschain->use
is 0, deletes the chain, and leaves a rule with a dangling pointer. An attacker can exploit this to create a UAF vulnerability.
On a non-Ksplice-patched system, the kernel fix prevents the vulnerability but does not alert the admin to an attack attempt. With Ksplice, the intrusion is prevented and logged.
Ksplice lets you patch vulnerabilities and critical bugs on running systems without rebooting. Find out what patches you can apply with Ksplice Inspector. Learn more at ksplice.oracle.com.
If this work interests you, consider applying to the Ksplice team! Reach us at ksplice-support_ww@oracle.com.