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);