Prevent a double softc free.

- Keep track if the softc was allocated externally or not.
- Only try to deallocate it if it was allocated internally.

Do not try to free the softc if we were not the ones allocating it.

- Avoid a double free on consecutive calls to device_set_softc.

Change-Id: Ibb38e54e9dfd2a80dbb53920970bead626da8ba1
Reviewed-on: https://review.haiku-os.org/c/1441
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Bruno Albuquerque 2019-05-08 00:47:09 -07:00
parent 1712a3c957
commit 7f6254d1e9
2 changed files with 13 additions and 3 deletions

View File

@ -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;
}

View File

@ -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().
};