CVE-2021-47049: Linux Kernel Vulnerability Resolved – Use After Free in __vmbus_open()

A vulnerability within the Linux kernel has been identified and resolved, specifically affecting the __vmbus_open() function in the drivers/hv/vmbus subsystem. The issue is related to a use after free scenario, where a variable ("open_info") is not properly handled, causing potential security concerns. This article will discuss the details of the vulnerability, provide a code snippet demonstrating the solution, and include links to original references.

Details

The vulnerability, tracked as CVE-2021-47049, impacts the __vmbus_open() function within the Linux kernel's Hyper-V Virtual Machine Bus (VMBus) driver. The VMBus driver is responsible for managing communication between the host operating system and its guest virtual machines.

In this case, a memory leak occurs when the "open_info" variable is added to the &vmbus_connection.chn_msg_list. During error handling, the "open_info" variable is erroneously freed without being removed from the list first, leading to a use after free vulnerability. To mitigate this issue, it is necessary to first remove the "open_info" variable from the list and then free it.

Here is the code snippet, which shows the fix applied in the __vmbus_open() function

static int __vmbus_open(struct vmbus_channel *newchannel,
			 const struct vmbus_channel_open_info *oinfo)
{
	struct vmbus_channel_open_msg *open_info;
	int ret;

	open_info = kzalloc(sizeof(*open_info), GFP_KERNEL);
	if (!open_info)
		return -ENOMEM;

	memcpy(&open_info->channel_msg.open, &oinfo->open, sizeof(oinfo->open));

	open_info->channel_msg.header.msgtype = CHANNELMSG_OPENCHANNEL;
	init_completion(&open_info->waitevent);

	spin_lock(&vmbus_connection.channel_mgmt_lock);
	list_add_tail(&open_info->msglistentry, &vmbus_connection.chn_msg_list);
	spin_unlock(&vmbus_connection.channel_mgmt_lock);

	ret = vmbus_post_msg(newchannel->primary_channel,
			     &open_info->channel_msg, sizeof(oinfo->open));
	if (ret != ) {
		spin_lock(&vmbus_connection.channel_mgmt_lock);
		list_del(&open_info->msglistentry);
		spin_unlock(&vmbus_connection.channel_mgmt_lock);
		kfree(open_info);
		return ret;
	}
	wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
	spin_lock(&vmbus_connection.channel_mgmt_lock);
	list_del(&open_info->msglistentry);
	spin_unlock(&vmbus_connection.channel_mgmt_lock);

	ret = open_info->vchannelopen_result;
	kfree(open_info);

	return ret;
}

The above code snippet demonstrates how the "open_info" variable is now being removed from the &vmbus_connection.chn_msg_list before being freed, addressing the use after free vulnerability.

Linux kernel Git commit implementing the fix:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1af9edbb56b2359c6b8e9bcbc9279d059ab805b3

Official CVE details:

https://nvd.nist.gov/vuln/detail/CVE-2021-47049

Conclusion

The Linux kernel vulnerability, CVE-2021-47049, which affected the __vmbus_open() function within the drivers/hv/vmbus subsystem, has been resolved. By properly handling the "open_info" variable during error handling, the use after free issue was mitigated. Updating to a version of the Linux kernel that includes this fix is strongly recommended to prevent potential security risks.

Timeline

Published on: 02/28/2024 09:15:40 UTC
Last modified on: 05/29/2024 05:01:13 UTC