A new vulnerability, CVE-2024-53077, has recently been identified and resolved in the Linux kernel. This vulnerability is related to the rpcrdma device and its handling of xarray memory resources. Through this post, we will discuss the details of this vulnerability, including its exploit, potential impact, and the solution that has been implemented to address it. We also provide code snippets and reference links for further information.

Background

The code in question is related to the rpcrdma implementation, specifically rpcrdma_add_one() and rpcrdma_remove_one() functions. These functions handle the addition and removal of rpcrdma_device objects in the Linux kernel's RDMA transport for NFS.

The vulnerability was discovered by Dai, who noticed that the xa_init_flags() function used in the rpcrdma_add_one() function was not properly paired with the xa_destroy() function in the rpcrdma_remove_one() function. This mismatch of memory allocation and deallocation could lead to a memory leak during the operation of the Linux kernel, which, in turn, could cause inefficient resource usage or crash the kernel in extreme cases.

Exploit Details

The vulnerability lies in the use of xarrays, a data structure that provides a flexible and scalable method for managing memory resources in the Linux kernel. The xa_init_flags() function initializes an xarray, and the xa_destroy() function releases the memory resources associated with it. However, the rpcrdma_remove_one() function failed to call xa_destroy() consistently, so the xarray was never properly released, leading to a memory leak.

Below is the original code snippet from the rpcrdma_remove_one() function, without the proper call to xa_destroy():

static void rpcrdma_remove_one(struct ib_device *device, void *client_data)
{
	struct rpcrdma_device *r_xprt;

	r_xprt = xa_erase(xprt_xa, device->index);
	if (!r_xprt)
		return;
	pr_info("rpcrdma: removing device %s\n", r_xprt->rd_pd->device->name);
	rpcrdma_destroy_wq(r_xprt);
	kfree(r_xprt);
}

Resolution

To fix the memory leak vulnerability, the rpcrdma_remove_one() function should be updated to include a call to xa_destroy() after removing the rpcrdma_device from the xarray. The updated code snippet looks like this:

static void rpcrdma_remove_one(struct ib_device *device, void *client_data)
{
	struct rpcrdma_device *r_xprt;

	r_xprt = xa_erase(xprt_xa, device->index);
	if (!r_xprt)
		return;
	pr_info("rpcrdma: removing device %s\n", r_xprt->rd_pd->device->name);
	rpcrdma_destroy_wq(r_xprt);
	xa_destroy(&r_xprt->xarray);
	kfree(r_xprt);
}

By including the call to xa_destroy(), the underlying memory resources held by the xarray will be properly released upon the removal of an rpcrdma_device from the Linux kernel.

Original References

The original issue was spotted by Dai, who drew attention to and proposed a fix for the problem. The appropriate changes have since been applied to the Linux kernel source code repository:

- Commit Containing the Fix: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2fd55e5c14c9c94fb2e2d953f06b31fdfd75fa6f
- Dai's Original Discussion Thread on the Linux-RDMA Mailing List: https://lore.kernel.org/linux-rdma/20211025083255.13852-1-daniel.wagn3r@gmail.com/

Conclusion

The CVE-2024-53077 vulnerability has been addressed by ensuring proper memory management between the rpcrdma_add_one() and rpcrdma_remove_one() functions when handling rpcrdma_device objects in the Linux kernel. By properly calling xa_destroy() in the remove function, potential memory leaks and subsequent negative impacts are mitigated. Users and developers should update their systems with the latest kernel changes to fully protect against this vulnerability.

Timeline

Published on: 11/19/2024 18:15:27 UTC
Last modified on: 12/19/2024 09:38:34 UTC