[Bug 295649] Fix bhnd_pmu_core_attach() cleanup on PMU attach failure

From: <bugzilla-noreply_at_freebsd.org>
Date: Wed, 27 May 2026 16:15:59 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295649

            Bug ID: 295649
           Summary: Fix bhnd_pmu_core_attach() cleanup on PMU attach
                    failure
           Product: Base System
           Version: 14.4-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: lihaoxiang@isrc.iscas.ac.cn

Created attachment 271259
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=271259&action=edit
possible patch

bhnd_pmu_core_attach() leaks the per-core PMU state allocated by
bhnd_alloc_pmu() when the subsequent bhnd_pmu_attach() call fails. I tested
this on FreeBSD 14.4-RELEASE amd64, but the affected code path does not appear
to be specific to this version.

In bhnd_pmu_core_attach(), the register resource is allocated first, then
bhnd_alloc_pmu() is called. If bhnd_pmu_attach() later fails, the code releases
the register resource but does not call bhnd_release_pmu().

This leaves the PMU allocation owned by the bhnd bus child active. The API
contract in bhnd.h says the register resource must remain allocated until after
bhnd_release_pmu(), so the expected unwind order is to call bhnd_release_pmu()
before releasing the register resource.

I tested this on FreeBSD 14.4-RELEASE amd64 in QEMU. I do not have real
bhnd/bcma/siba hardware, and the VM has no Broadcom PCI device, so I used a
kernel-side fault-injection harness. The harness creates a synthetic bhnd bus
and bhnd_pmu child, then forces bhnd_pmu_attach() to fail by returning ENODEV
from the parent bus read_board_info method. This exercises the real
bhnd_pmu_core_attach() error path.

To verify the leak, the harness' BHND_BUS_ALLOC_PMU method allocates from a
dedicated malloc type, bhndpmuflt, and leaves the allocation active unless
BHND_BUS_RELEASE_PMU is called.

After the forced attach failure, vmstat -m showed:
        Type        Use  Memory  Req  Size(s)
        bhndpmuflt    1      16    1  16
This shows that bhnd_alloc_pmu() succeeded, but the failure path did not call
bhnd_release_pmu().

Thus, cleanup is necessary on the bhnd_pmu_attach() failure path. There is also
a related cleanup issue by inspection in bhnd_pmu_core_detach(). I didn't test
it, but bhnd_release_pmu() is nessasry from my view.

-- 
You are receiving this mail because:
You are the assignee for the bug.