aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Atkinson <gavin@FreeBSD.org>2024-12-27 16:55:05 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2024-12-27 16:55:05 +0000
commit6ea1ce222c7ce2aeae7ecd3558c731cb8c05a37e (patch)
treeeb0216dbb9a6df673d75c6e207d7560da8b9e0dd
parent2e09cef8dc6f46faba8bab87c42c3f19ba2ffe87 (diff)
bhnd: Fix a few use after frees when releasing resources
The resource list entry needs to be looked up using rman_get_* prior to releasing the resource. Fixes: 9dbf5b0e6876 new-bus: Remove the 'rid' and 'type' arguments from BUS_RELEASE_RESOURCE
-rw-r--r--sys/dev/bhnd/bhndb/bhndb.c17
-rw-r--r--sys/dev/bhnd/cores/chipc/chipc.c6
2 files changed, 13 insertions, 10 deletions
diff --git a/sys/dev/bhnd/bhndb/bhndb.c b/sys/dev/bhnd/bhndb/bhndb.c
index eeff088ffdde..511beae0cc25 100644
--- a/sys/dev/bhnd/bhndb/bhndb.c
+++ b/sys/dev/bhnd/bhndb/bhndb.c
@@ -1037,7 +1037,7 @@ static int
bhndb_release_resource(device_t dev, device_t child, struct resource *r)
{
struct bhndb_softc *sc;
- struct resource_list_entry *rle;
+ struct resource_list_entry *rle = NULL;
bool passthrough;
int error;
@@ -1058,16 +1058,17 @@ bhndb_release_resource(device_t dev, device_t child, struct resource *r)
return (error);
}
+ /* Check for resource list entry */
+ if (!passthrough)
+ rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
+ rman_get_type(r), rman_get_rid(r));
+
if ((error = rman_release_resource(r)))
return (error);
- if (!passthrough) {
- /* Clean resource list entry */
- rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
- rman_get_type(r), rman_get_rid(r));
- if (rle != NULL)
- rle->res = NULL;
- }
+ /* Clean resource list entry */
+ if (rle != NULL)
+ rle->res = NULL;
return (0);
}
diff --git a/sys/dev/bhnd/cores/chipc/chipc.c b/sys/dev/bhnd/cores/chipc/chipc.c
index 010ebbbd6cb2..09ca4d8884e6 100644
--- a/sys/dev/bhnd/cores/chipc/chipc.c
+++ b/sys/dev/bhnd/cores/chipc/chipc.c
@@ -893,6 +893,10 @@ chipc_release_resource(device_t dev, device_t child, struct resource *r)
if (cr == NULL)
return (EINVAL);
+ /* Cache rle */
+ rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
+ rman_get_type(r), rman_get_rid(r));
+
/* Deactivate resources */
error = bus_generic_rman_release_resource(dev, child, r);
if (error != 0)
@@ -902,8 +906,6 @@ chipc_release_resource(device_t dev, device_t child, struct resource *r)
chipc_release_region(sc, cr, RF_ALLOCATED);
/* Clear reference from the resource list entry if exists */
- rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
- rman_get_type(r), rman_get_rid(r));
if (rle != NULL)
rle->res = NULL;