diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index 0d5b6385c3..ae3adf783c 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -268,7 +268,13 @@ device_get_softc(device_t dev) void device_set_softc(device_t dev, void *softc) { + if (!(dev->flags & DEVICE_SOFTC_SET)) { + // Not externally allocated. We own it so we must clean it up. + free(dev->softc); + } + dev->softc = softc; + dev->flags |= DEVICE_SOFTC_SET; } @@ -445,7 +451,10 @@ device_delete_child(device_t parent, device_t child) if (parent->flags & DEVICE_DESC_ALLOCED) free((char *)parent->description); - free(parent->softc); + // Delete softc if we were the ones to allocate it. + if (!(parent->flags & DEVICE_SOFTC_SET)) + free(parent->softc); + free(parent); return 0; } diff --git a/src/libs/compat/freebsd_network/device.h b/src/libs/compat/freebsd_network/device.h index 706144abf8..fbf04ec347 100644 --- a/src/libs/compat/freebsd_network/device.h +++ b/src/libs/compat/freebsd_network/device.h @@ -35,11 +35,12 @@ struct root_device_softc { }; enum { - DEVICE_OPEN = 1 << 0, + DEVICE_OPEN = 1 << 0, DEVICE_CLOSED = 1 << 1, DEVICE_NON_BLOCK = 1 << 2, DEVICE_DESC_ALLOCED = 1 << 3, - DEVICE_ATTACHED = 1 << 4 + DEVICE_ATTACHED = 1 << 4, + DEVICE_SOFTC_SET = 1 << 5 // Set through device_set_softc(). };