The branch main has been updated by bnovkov:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6e8233df18c8008e1a244c8528521a0369f61369

commit 6e8233df18c8008e1a244c8528521a0369f61369
Author:     Bojan Novković <bnov...@freebsd.org>
AuthorDate: 2024-12-21 10:55:57 +0000
Commit:     Bojan Novković <bnov...@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 (i...@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);

Reply via email to