CVE-2024-27392: Fixing Double-Free Vulnerability in Linux Kernel's NVMe Host

A significant security vulnerability has been discovered and resolved in the NVMe (Non-Volatile Memory Express) host module of the Linux kernel. The issue, identified as CVE-2024-27392, is related to a double-free in the handling of struct nvme_id_ns instances. It poses a potential risk to system stability and security, as a double-free of memory can lead to system crashes or potentially be exploited by malicious users. This post will take a closer look at the discovery, root cause, and resolution of this vulnerability.

Background

The Linux kernel NVMe host module is responsible for managing NVMe storage devices. As part of this management, it handles the identification and configuration of namespaces, which are logical abstractions used to isolate and group NVMe storage resources.

The vulnerability, discovered in the ns_update_nuse() function, occurs when nvme_identify_ns() fails, freeing the pointer to the struct nvme_id_ns before returning. However, ns_update_nuse() calls kfree() for the pointer even when nvme_identify_ns() fails, which results in a double-free.

This issue was first observed with the blktests nvme/045 with the proposed patches [1] on the kernel version 6.8-rc7. In the sections below, we'll detail the root cause of this vulnerability and the fix implemented to address it.

The problematic code snippet can be found in the ns_update_nuse() function

static int ns_update_nuse(struct nvme_ns *ns)
{
    ...
    // nvme_identify_ns() call, which can free the id pointer if it fails.
    error = nvme_identify_ns(ns->ctrl, ns->head->ns_id, &id);
    ...
    // kfree() called unconditionally for the id pointer.
    kfree(id);
    ...
}

As seen above, the pointer 'id' is freed unconditionally with kfree() after the call to nvme_identify_ns().

Proposed Fix

To fix this double-free vulnerability, the kfree() call should only be executed if the nvme_identify_ns() function call is successful. The following code snippet highlights the proposed fix:

static int ns_update_nuse(struct nvme_ns *ns)
{
    ...
    error = nvme_identify_ns(ns->ctrl, ns->head->ns_id, &id);
    if (error) {
        // Return directly if nvme_identify_ns() fails, avoiding a double-free.
        return error;
    }
    ...
    kfree(id);
    ...
}

References

[1] Proposed patch set for the Linux kernel: https://example.com/proposed-patches

Conclusion

In this post, we've detailed the discovery, root cause, and resolution of CVE-2024-27392, a double-free vulnerability in the Linux kernel NVMe host module. By skipping the unnecessary kfree() call when nvme_identify_ns() fails, the risk of system crashes and potential exploitation by malicious users is mitigated.

It is recommended that users running kernels affected by this vulnerability apply the patch or update their systems to a patched kernel version as soon as possible to ensure system stability and security.

Timeline

Published on: 05/01/2024 13:15:51 UTC
Last modified on: 05/29/2024 05:28:18 UTC