CVE-2022-49847 in Linux
요약
\~에 의해 VulDB • 2026. 06. 30.
Based on the kernel log snippet provided, here is an analysis of the crash and potential causes.
### **Summary** The system crashed (Oops/Panic) in `phy_stop()` while unregistering a network device (`am65_cpsw_nuss`). This typically happens during driver removal or interface shutdown when there is a race condition, use-after-free, or invalid state access related to the PHY layer.
---
### **Key Call Trace Analysis** 1. **`phy_stop+0x18/0xf8`**: The crash occurred here. `phy_stop()` is called to stop communication with the physical layer (PHY). It likely accessed a NULL pointer or invalid memory structure (`priv->phydev` or similar) that was already freed or not properly initialized. 2. **`phylink_stop+0x38/0xf8`**: Called by `am65_cpsw_nuss_ndo_slave_stop`. This is the standard Linux PHYLINK framework stop routine. 3. **`am65_cpsw_nuss_ndo_slave_stop`**: The network driver's `.ndo_stop` callback for a slave interface (likely an Ethernet port on TI AM65x SoC). 4. **`__dev_close_many`, `unregister_netdevice...`**: These indicate the system is in the process of **unregistering** or bringing down the network device, likely during: - Driver removal (`am65_cpsw_nuss_remove`) - Interface shutdown (`ifconfig ethX down`) - System reboot/shutdown
---
### **Potential Causes**
#### 1. **Race Condition During Removal/Shutdown** - The most common cause is a race between: - A hardware interrupt or NAPI poll handler still running (e.g., packet reception/transmission). - The driver's `remove` or `stop` function freeing resources (`phydev`, buffers, etc.). - If an interrupt fires after the PHY structure is freed but before it’s fully cleaned up, accessing `priv->phydev` in `phy_stop()` will crash.
#### 2. **NULL Pointer Dereference** - In `phy_stop()`, if `phylink_get_phydev(pl)` returns NULL (because the PHY was never attached or already detached), and the code doesn’t check for it, a crash occurs. - Check if `priv->phy` is valid before calling `phy_stop()` in your driver’s stop/remove path.
#### 3. **Improper Cleanup Order** - The driver might be freeing resources (like memory allocated for PHY structures) too early, while the network stack still holds references to them via `netdev`. - Ensure that: ```c unregister_netdevice(netdev); // Frees netdev and triggers ndo_stop ``` is called **after** all hardware resources are safely stopped.
#### 4. **PHY Link State Mismatch** - If the PHY link state changed unexpectedly (e.g., cable unplugged) during shutdown, `phylink` might be in an inconsistent state when `phy_stop()` is called.
---
### **Debugging Steps & Fixes**
#### ✅ **1. Check for NULL Pointers in Driver Code** In your driver’s `.ndo_stop` or `.remove`, ensure you handle cases where the PHY device may not be initialized: ```c static int am65_cpsw_nuss_ndo_slave_stop(struct net_device *ndev) {
struct cpsw_priv *priv = netdev_priv(ndev);
// Ensure phylink is valid before stopping if (priv->phylink) {
phylink_stop(priv->phylink); } else {
dev_warn(&ndev->dev, "phylink not initialized\n"); }
return 0; } ```
#### ✅ **2. Disable Interrupts Before Cleanup** Ensure all interrupts are disabled and NAPI is flushed before freeing resources: ```c static void am65_cpsw_nuss_remove(struct platform_device *pdev) {
struct cpsw_priv *priv = platform_get_drvdata(pdev);
// 1. Stop network device (triggers ndo_stop -> phylink_stop) unregister_netdev(priv->ndev);
// 2. Disable all interrupts disable_irq(priv->irq);
// 3. Flush NAPI and workqueues napi_disable(&priv->napi); cancel_work_sync(&priv->work);
// 4. Free resources (PHY, buffers, etc.) } ```
#### ✅ **3. Check for Use-After-Free** Use `CONFIG_DEBUG_VM` or KASAN to detect if the crash is due
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.