The first trip into acpi_ut_update_ref_count() for an object where 'object->common.reference_count' is 1 and we are performing a REF_DECREMENT will result in 'new_count' being 0 and thus the object is deleted via acpi_ut_delete_internal_obj(). If for some reason we make a subsequent trip into acpi_ut_update_ref_count() with the same object, object->common.reference_count' will be 0 and performing a REF_DECREMENT will produce a warning msg "Reference Count is already zero, cannot decrement", 'new_count' will again be 0 and the already deleted object will be attempted to be deleted again via acpi_ut_delete_internal_obj(). Since the object deletion doesn't NULL the object the calls to acpi_ut_delete_internal_obj(), acpi_ut_delete_object_desc(), acpi_os_release_object(), kmem_cache_free() will operate on the object as if it hasn't been deleted. In many cases this can result in no issues, but if you are using the slab and a new object has been created with the same address this can be the cause slab corruption. Adding a check if we are decrementing to 0 for the first time and only calling acpi_ut_delete_internal_obj() in this case will prevent another attempt at deleting the object. Signed-off-by: Mark Asselstine <mark.asselstine@xxxxxxxxxxxxx> --- drivers/acpi/acpica/utdelete.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index 4c0d4e434196..c6b860fd9eb5 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -421,9 +421,9 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) ACPI_GET_FUNCTION_NAME, object, object->common.type, new_count)); - /* Actually delete the object on a reference count of zero */ + /* If we haven't already, actually delete the object on a reference count of zero */ - if (new_count == 0) { + if (new_count == 0 && original_count != 0) { acpi_ut_delete_internal_obj(object); } message = "Decrement"; -- 2.17.1