From 85f4cd60974d43ab4c7145b8e9b925a1e387ba6d Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Dec 16 2016 19:32:01 +0000 Subject: Ticket #48987 - Heap use after free in dblayer_close_indexes Description: Once an attribute info is deleted, its backpointer dblayer_handle_ai_backpointer in the dblayer handle needs to be set to NULL not to access the address again. We also need to set this to null from within the dblayer_close_indexes because there is no guarantee on the order that we free the handle or the attrinfo. https://fedorahosted.org/389/ticket/48987 Author: nhosoi, wibrown Review: nhosoi (Thanks!) (cherry picked from commit 99176404bfe76ee9fcf48b8b28750ec3979ec020) --- diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index 9e74d9b..d1d8972 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -2679,7 +2679,13 @@ int dblayer_close_indexes(backend *be) pDB = handle->dblayer_dbp; return_value |= pDB->close(pDB,0); next = handle->dblayer_handle_next; - *((dblayer_handle **)handle->dblayer_handle_ai_backpointer) = NULL; + /* If the backpointer is still valid, NULL the attrinfos ref to us + * This is important as there is no ordering guarantee between if the + * handle or the attrinfo is freed first! + */ + if (handle->dblayer_handle_ai_backpointer) { + *((dblayer_handle **)handle->dblayer_handle_ai_backpointer) = NULL; + } slapi_ch_free((void**)&handle); } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c index 7e44cfe..0cc6747 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c @@ -59,6 +59,10 @@ attrinfo_delete(struct attrinfo **pp) slapi_ch_free((void**)&((*pp)->ai_attrcrypt)); attr_done(&((*pp)->ai_sattr)); attrinfo_delete_idlistinfo(&(*pp)->ai_idlistinfo); + if ((*pp)->ai_dblayer) { + /* attriinfo is deleted. Cleaning up the backpointer at the same time. */ + ((dblayer_handle *)((*pp)->ai_dblayer))->dblayer_handle_ai_backpointer = NULL; + } slapi_ch_free((void**)pp); *pp= NULL; }