git: 6e8233df18c8 - main - hwpmc_x86: Fix NULL deref when loading on unsupported hardware
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 23 Dec 2024 10:06:50 UTC
The branch main has been updated by bnovkov:
URL: https://cgit.FreeBSD.org/src/commit/?id=6e8233df18c8008e1a244c8528521a0369f61369
commit 6e8233df18c8008e1a244c8528521a0369f61369
Author: Bojan Novković <bnovkov@FreeBSD.org>
AuthorDate: 2024-12-21 10:55:57 +0000
Commit: Bojan Novković <bnovkov@FreeBSD.org>
CommitDate: 2024-12-23 10:00:57 +0000
hwpmc_x86: Fix NULL deref when loading on unsupported hardware
The pmc_md_{intialize, finalize} routines rely on a machine-dependent
structure to register the appropriate PMC interrupt handler. However,
the vendor-specific routines that allocate this structure may return
NULL for unsupported hardware, leading to a panic when the hwpmc module
gets loaded. This patch adds additional checks that fix this issue.
Reported by: Michael Butler (imb@protected-networks.net)
Reviewed by: kib
Differential Revision: https://reviews.freebsd.org/D48168
---
sys/dev/hwpmc/hwpmc_x86.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c
index 2c6c4cd148bf..2903c25ef5c9 100644
--- a/sys/dev/hwpmc/hwpmc_x86.c
+++ b/sys/dev/hwpmc/hwpmc_x86.c
@@ -230,7 +230,7 @@ struct pmc_mdep *
pmc_md_initialize(void)
{
int i;
- struct pmc_mdep *md;
+ struct pmc_mdep *md = NULL;
/* determine the CPU kind */
if (cpu_vendor_id == CPU_VENDOR_AMD ||
@@ -238,17 +238,18 @@ pmc_md_initialize(void)
md = pmc_amd_initialize();
else if (cpu_vendor_id == CPU_VENDOR_INTEL)
md = pmc_intel_initialize();
- else
+
+ if (md == NULL)
return (NULL);
+ nmi_register_handler(md->pmd_intr);
/* disallow sampling if we do not have an LAPIC */
- if (md != NULL && !lapic_enable_pcint())
+ if (!lapic_enable_pcint())
for (i = 0; i < md->pmd_nclass; i++) {
if (i == PMC_CLASS_INDEX_SOFT)
continue;
md->pmd_classdep[i].pcd_caps &= ~PMC_CAP_INTERRUPT;
}
- nmi_register_handler(md->pmd_intr);
return (md);
}
@@ -256,9 +257,10 @@ pmc_md_initialize(void)
void
pmc_md_finalize(struct pmc_mdep *md)
{
-
- lapic_disable_pcint();
- nmi_remove_handler(md->pmd_intr);
+ if (md != NULL) {
+ lapic_disable_pcint();
+ nmi_remove_handler(md->pmd_intr);
+ }
if (cpu_vendor_id == CPU_VENDOR_AMD ||
cpu_vendor_id == CPU_VENDOR_HYGON)
pmc_amd_finalize(md);