fkie_cve-2022-49605
Vulnerability from fkie_nvd
Published
2025-02-26 07:01
Modified
2025-02-26 07:01
Severity ?
Summary
In the Linux kernel, the following vulnerability has been resolved:
igc: Reinstate IGC_REMOVED logic and implement it properly
The initially merged version of the igc driver code (via commit
146740f9abc4, "igc: Add support for PF") contained the following
IGC_REMOVED checks in the igc_rd32/wr32() MMIO accessors:
u32 igc_rd32(struct igc_hw *hw, u32 reg)
{
u8 __iomem *hw_addr = READ_ONCE(hw->hw_addr);
u32 value = 0;
if (IGC_REMOVED(hw_addr))
return ~value;
value = readl(&hw_addr[reg]);
/* reads should not return all F's */
if (!(~value) && (!reg || !(~readl(hw_addr))))
hw->hw_addr = NULL;
return value;
}
And:
#define wr32(reg, val) \
do { \
u8 __iomem *hw_addr = READ_ONCE((hw)->hw_addr); \
if (!IGC_REMOVED(hw_addr)) \
writel((val), &hw_addr[(reg)]); \
} while (0)
E.g. igb has similar checks in its MMIO accessors, and has a similar
macro E1000_REMOVED, which is implemented as follows:
#define E1000_REMOVED(h) unlikely(!(h))
These checks serve to detect and take note of an 0xffffffff MMIO read
return from the device, which can be caused by a PCIe link flap or some
other kind of PCI bus error, and to avoid performing MMIO reads and
writes from that point onwards.
However, the IGC_REMOVED macro was not originally implemented:
#ifndef IGC_REMOVED
#define IGC_REMOVED(a) (0)
#endif /* IGC_REMOVED */
This led to the IGC_REMOVED logic to be removed entirely in a
subsequent commit (commit 3c215fb18e70, "igc: remove IGC_REMOVED
function"), with the rationale that such checks matter only for
virtualization and that igc does not support virtualization -- but a
PCIe device can become detached even without virtualization being in
use, and without proper checks, a PCIe bus error affecting an igc
adapter will lead to various NULL pointer dereferences, as the first
access after the error will set hw->hw_addr to NULL, and subsequent
accesses will blindly dereference this now-NULL pointer.
This patch reinstates the IGC_REMOVED checks in igc_rd32/wr32(), and
implements IGC_REMOVED the way it is done for igb, by checking for the
unlikely() case of hw_addr being NULL. This change prevents the oopses
seen when a PCIe link flap occurs on an igc adapter.
References
Impacted products
Vendor | Product | Version |
---|
{ "cveTags": [], "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nigc: Reinstate IGC_REMOVED logic and implement it properly\n\nThe initially merged version of the igc driver code (via commit\n146740f9abc4, \"igc: Add support for PF\") contained the following\nIGC_REMOVED checks in the igc_rd32/wr32() MMIO accessors:\n\n\tu32 igc_rd32(struct igc_hw *hw, u32 reg)\n\t{\n\t\tu8 __iomem *hw_addr = READ_ONCE(hw-\u003ehw_addr);\n\t\tu32 value = 0;\n\n\t\tif (IGC_REMOVED(hw_addr))\n\t\t\treturn ~value;\n\n\t\tvalue = readl(\u0026hw_addr[reg]);\n\n\t\t/* reads should not return all F\u0027s */\n\t\tif (!(~value) \u0026\u0026 (!reg || !(~readl(hw_addr))))\n\t\t\thw-\u003ehw_addr = NULL;\n\n\t\treturn value;\n\t}\n\nAnd:\n\n\t#define wr32(reg, val) \\\n\tdo { \\\n\t\tu8 __iomem *hw_addr = READ_ONCE((hw)-\u003ehw_addr); \\\n\t\tif (!IGC_REMOVED(hw_addr)) \\\n\t\t\twritel((val), \u0026hw_addr[(reg)]); \\\n\t} while (0)\n\nE.g. igb has similar checks in its MMIO accessors, and has a similar\nmacro E1000_REMOVED, which is implemented as follows:\n\n\t#define E1000_REMOVED(h) unlikely(!(h))\n\nThese checks serve to detect and take note of an 0xffffffff MMIO read\nreturn from the device, which can be caused by a PCIe link flap or some\nother kind of PCI bus error, and to avoid performing MMIO reads and\nwrites from that point onwards.\n\nHowever, the IGC_REMOVED macro was not originally implemented:\n\n\t#ifndef IGC_REMOVED\n\t#define IGC_REMOVED(a) (0)\n\t#endif /* IGC_REMOVED */\n\nThis led to the IGC_REMOVED logic to be removed entirely in a\nsubsequent commit (commit 3c215fb18e70, \"igc: remove IGC_REMOVED\nfunction\"), with the rationale that such checks matter only for\nvirtualization and that igc does not support virtualization -- but a\nPCIe device can become detached even without virtualization being in\nuse, and without proper checks, a PCIe bus error affecting an igc\nadapter will lead to various NULL pointer dereferences, as the first\naccess after the error will set hw-\u003ehw_addr to NULL, and subsequent\naccesses will blindly dereference this now-NULL pointer.\n\nThis patch reinstates the IGC_REMOVED checks in igc_rd32/wr32(), and\nimplements IGC_REMOVED the way it is done for igb, by checking for the\nunlikely() case of hw_addr being NULL. This change prevents the oopses\nseen when a PCIe link flap occurs on an igc adapter." }, { "lang": "es", "value": "En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: igc: Restablecer la l\u00f3gica IGC_REMOVED e implementarla correctamente La versi\u00f3n fusionada inicialmente del c\u00f3digo del controlador igc (a trav\u00e9s de el commit 146740f9abc4, \"igc: Agregar soporte para PF\") conten\u00eda las siguientes comprobaciones IGC_REMOVED checks in the igc_rd32/wr32() MMIO accessors: u32 igc_rd32(struct igc_hw *hw, u32 reg) { u8 __iomem *hw_addr = READ_ONCE(hw-\u0026gt;hw_addr); u32 value = 0; if (IGC_REMOVED(hw_addr)) return ~value; value = readl(\u0026amp;hw_addr[reg]); /* reads should not return all F\u0027s */ if (!(~value) \u0026amp;\u0026amp; (!reg || !(~readl(hw_addr)))) hw-\u0026gt;hw_addr = NULL; return value; } And: #define wr32(reg, val) \\ do { \\ u8 __iomem *hw_addr = READ_ONCE((hw)-\u0026gt;hw_addr); \\ if (!IGC_REMOVED(hw_addr)) \\ writel((val), \u0026amp;hw_addr[(reg)]); \\ } while (0) Por ejemplo, igb tiene verificaciones similares en sus accesores MMIO y tiene una macro similar E1000_REMOVED, que se implementa de la siguiente manera: #define E1000_REMOVED(h) Unlikely(!(h)) Estas verificaciones sirven para detectar y tomar nota de un retorno de lectura MMIO 0xffffffff del dispositivo, que puede ser causado por una falla en el enlace PCIe o alg\u00fan otro tipo de error de bus PCI, y para evitar realizar lecturas y escrituras MMIO desde ese punto en adelante. Sin embargo, la macro IGC_REMOVED no se implement\u00f3 originalmente: #ifndef IGC_REMOVED #define IGC_REMOVED(a) (0) #endif /* IGC_REMOVED */ Esto provoc\u00f3 que la l\u00f3gica IGC_REMOVED se eliminara por completo en una confirmaci\u00f3n posterior (confirmaci\u00f3n 3c215fb18e70, \"igc: eliminar la funci\u00f3n IGC_REMOVED\"), con el fundamento de que dichas comprobaciones solo son importantes para la virtualizaci\u00f3n y que igc no admite la virtualizaci\u00f3n, pero un dispositivo PCIe puede desconectarse incluso sin que se utilice la virtualizaci\u00f3n y, sin las comprobaciones adecuadas, un error de bus PCIe que afecte a un adaptador igc provocar\u00e1 varias desreferencias de puntero NULL, ya que el primer acceso despu\u00e9s del error establecer\u00e1 hw-\u0026gt;hw_addr en NULL, y los accesos posteriores desreferenciar\u00e1n ciegamente este puntero ahora NULL. Este parche restablece las comprobaciones IGC_REMOVED en igc_rd32/wr32() e implementa IGC_REMOVED de la forma en que se hace para igb, comprobando el caso improbable() de que hw_addr sea NULL. Este cambio evita los errores que se observan cuando se produce una falla en el enlace PCIe en un adaptador igc." } ], "id": "CVE-2022-49605", "lastModified": "2025-02-26T07:01:36.000", "metrics": {}, "published": "2025-02-26T07:01:36.000", "references": [ { "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "url": "https://git.kernel.org/stable/c/16cb6717f4f42487ef10583eb8bc98e7d1e33d65" }, { "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "url": "https://git.kernel.org/stable/c/70965b6e5c03aa70cc754af1226b9f9cde0c4bf3" }, { "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "url": "https://git.kernel.org/stable/c/77836dbe35382aaf8108489060c5c89530c77494" }, { "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "url": "https://git.kernel.org/stable/c/7c1ddcee5311f3315096217881d2dbe47cc683f9" }, { "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "url": "https://git.kernel.org/stable/c/e75b73081f1ec169518773626c2ff3950476660b" } ], "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "vulnStatus": "Awaiting Analysis" }
Loading…
Loading…
Sightings
Author | Source | Type | Date |
---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.
Loading…
Loading…