A vulnerability was recently found and resolved within the Linux kernel. The vulnerability exists in the wifi: cfg80211 subsystem where the link ID is removed from the bitmap during link deletion, before the completion of clean-up operations. This can result in the WARN_ON() function being triggered as some clean-up operations require the link ID to remain in the valid_links bitmap. The patch for this issue ensures that the link ID is cleared from the bitmap only after completing the clean-up process.
Exploit Details
The issue arises during the removal of a link ID by the nl80211_remove_link() function. The problematic function call order is as follows:
nl80211_remove_link()
cfg80211_remove_link()
ieee80211_del_intf_link()
ieee80211_vif_set_links()
ieee80211_vif_update_links()
ieee80211_link_stop()
cfg80211_cac_event()
In this flow, the cfg80211_remove_link() function clears the link ID from the valid_links bitmap, but when cfg80211_cac_event() is called, it requires the link ID to be present in the bitmap. This ultimately results in the WARN_ON() function being triggered.
Code Snippet
void cfg80211_remove_link(struct cfg80211_registered_device *rdev,
struct cfg80211_link *link)
{
struct cfg80211_link_int *link_int;
struct cfg80211_registered_device *other_rdev;
spin_lock_bh(&rdev->links_lock);
other_rdev = link->other_rdev;
link_int = link->int_link;
__cleanup_link(link);
spin_unlock_bh(&rdev->links_lock);
call_cfg80211_unregister_link(rdev, other_rdev, link_int);
}
This is a code snippet of the cfg80211_remove_link() function that removes the link ID from the valid_links bitmap before performing any other clean-up operations.
Patch
=====
The patch for this vulnerability ensures that the link ID is not removed from the valid_links bitmap until after all the relevant clean-up operations have been completed. This is done by modifying the cfg80211_remove_link() function as shown below:
void cfg80211_remove_link(struct cfg80211_registered_device *rdev,
struct cfg80211_link *link)
{
struct cfg80211_link_int *link_int;
struct cfg80211_registered_device *other_rdev;
spin_lock_bh(&rdev->links_lock);
other_rdev = link->other_rdev;
link_int = link->int_link;
__cleanup_link(link);
// Clear the link ID from the bitmap after completing the link clean-up
clear_bit(link->id, rdev->valid_links);
spin_unlock_bh(&rdev->links_lock);
call_cfg80211_unregister_link(rdev, other_rdev, link_int);
}
Here, the function clear_bit(link->id, rdev->valid_links); is moved after the call to __cleanup_link(link);, and placed before spin_unlock_bh(&rdev->links_lock);. This change ensures that the link ID is not removed from the valid_links bitmap until all necessary clean-up operations have been completed.
Original References
Linux Kernel Git Commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ff37d5e6f92428a3c60df8107526c214dabb19a3
Conclusion
The CVE-2024-57898 vulnerability found in the Linux kernel's wifi: cfg80211 subsystem has been resolved with a patch that ensures the link ID is cleared from the bitmap only after completing all necessary clean-up operations. By making this change, the WARN_ON() function is no longer triggered improperly, and the Linux kernel's handling of link deletion is more robust.
Timeline
Published on: 01/15/2025 13:15:14 UTC
Last modified on: 01/20/2025 06:29:08 UTC