CVE-2021-47554 in Linux
Summary
by MITRE • 05/24/2024
In the Linux kernel, the following vulnerability has been resolved:
vdpa_sim: avoid putting an uninitialized iova_domain
The system will crash if we put an uninitialized iova_domain, this could happen when an error occurs before initializing the iova_domain in vdpasim_create().
BUG: kernel NULL pointer dereference, address: 0000000000000000 ... RIP: 0010:__cpuhp_state_remove_instance+0x96/0x1c0 ... Call Trace: put_iova_domain+0x29/0x220 vdpasim_free+0xd1/0x120 [vdpa_sim]
vdpa_release_dev+0x21/0x40 [vdpa]
device_release+0x33/0x90 kobject_release+0x63/0x160 vdpasim_create+0x127/0x2a0 [vdpa_sim]
vdpasim_net_dev_add+0x7d/0xfe [vdpa_sim_net]
vdpa_nl_cmd_dev_add_set_doit+0xe1/0x1a0 [vdpa]
genl_family_rcv_msg_doit+0x112/0x140 genl_rcv_msg+0xdf/0x1d0 ...
So we must make sure the iova_domain is already initialized before put it.
In addition, we may get the following warning in this case: WARNING: ... drivers/iommu/iova.c:344 iova_cache_put+0x58/0x70
So we must make sure the iova_cache_put() is invoked only if the iova_cache_get() is already invoked. Let's fix it together.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 01/16/2025
The vulnerability CVE-2021-47554 represents a critical null pointer dereference issue within the Linux kernel's virtual device passthrough architecture implementation. This flaw exists in the vdpa_sim driver component which handles virtual device simulation for VDPA (Virtual Device Passthrough Architecture) functionality. The vulnerability stems from improper initialization handling of iova_domain structures during device creation operations, specifically within the vdpasim_create() function where error conditions can lead to premature cleanup attempts on uninitialized data structures.
The technical execution path of this vulnerability begins with the vdpasim_create() function attempting to initialize a virtual device but encountering errors before completing the iova_domain initialization process. When the error occurs, the system attempts to call put_iova_domain() on what is essentially a null or uninitialized iova_domain structure, resulting in a kernel NULL pointer dereference at address 0x0000000000000000. The call trace demonstrates this progression through kernel subsystems including __cpuhp_state_remove_instance, put_iova_domain, vdpasim_free, and ultimately to vdpasim_create, indicating a cascading failure where cleanup operations are invoked on improperly initialized memory structures.
The operational impact of this vulnerability is severe as it can cause complete system crashes or kernel oops conditions, effectively rendering the affected system unstable and potentially leading to denial of service scenarios. This issue particularly affects systems utilizing VDPA virtualization capabilities and can be exploited by malicious actors to trigger kernel panics or system reboots. The vulnerability's classification aligns with CWE-476 which addresses NULL Pointer Dereference, and its exploitation patterns correspond to ATT&CK technique T1499.004 for Network Denial of Service and T1566.001 for Phishing with Malicious Attachments in attack scenarios involving kernel-level privilege escalation.
The fix implemented addresses the core issue by ensuring proper initialization state validation before any cleanup operations are performed on iova_domain structures. The solution requires that iova_cache_put() is only invoked when iova_cache_get() has been successfully executed, preventing the erroneous cleanup of uninitialized memory regions. This approach follows established kernel development practices for resource management and aligns with the Linux kernel's defensive programming principles. The mitigation strategy specifically targets the race condition between initialization and cleanup phases, ensuring that all memory management operations within the VDPA simulation framework maintain proper state consistency. Additionally, the fix addresses potential warning conditions in drivers/iommu/iova.c at line 344 where iova_cache_put() would be invoked without proper corresponding iova_cache_get() calls, preventing both immediate crashes and subsequent warning generation that could indicate deeper memory management issues.