From owner-svn-src-all@FreeBSD.ORG Wed Nov 5 12:32:43 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 13E1A1065675; Wed, 5 Nov 2008 12:32:43 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 019488FC13; Wed, 5 Nov 2008 12:32:43 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mA5CWgPg027011; Wed, 5 Nov 2008 12:32:42 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mA5CWgbB027010; Wed, 5 Nov 2008 12:32:42 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <200811051232.mA5CWgbB027010@svn.freebsd.org> From: Konstantin Belousov Date: Wed, 5 Nov 2008 12:32:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r184685 - stable/7/libexec/rtld-elf X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Nov 2008 12:32:43 -0000 Author: kib Date: Wed Nov 5 12:32:42 2008 New Revision: 184685 URL: http://svn.freebsd.org/changeset/base/184685 Log: MFC r182698 (by kan): Make sure internal rtld malloc routines are not called from unlocked contexts as rtld's malloc is not thread safe and is only supposed to be called with exclusive bind lock already held. Approved by: re (kensmith), kan Modified: stable/7/libexec/rtld-elf/ (props changed) stable/7/libexec/rtld-elf/rtld.c Modified: stable/7/libexec/rtld-elf/rtld.c ============================================================================== --- stable/7/libexec/rtld-elf/rtld.c Wed Nov 5 12:28:44 2008 (r184684) +++ stable/7/libexec/rtld-elf/rtld.c Wed Nov 5 12:32:42 2008 (r184685) @@ -106,8 +106,8 @@ static int load_needed_objects(Obj_Entry static int load_preload_objects(void); static Obj_Entry *load_object(const char *, const Obj_Entry *); static Obj_Entry *obj_from_addr(const void *); -static void objlist_call_fini(Objlist *); -static void objlist_call_init(Objlist *); +static void objlist_call_fini(Objlist *, int *lockstate); +static void objlist_call_init(Objlist *, int *lockstate); static void objlist_clear(Objlist *); static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *); static void objlist_init(Objlist *); @@ -512,8 +512,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_ r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */ - objlist_call_init(&initlist); lockstate = wlock_acquire(rtld_bind_lock); + objlist_call_init(&initlist, &lockstate); objlist_clear(&initlist); wlock_release(rtld_bind_lock, lockstate); @@ -1433,7 +1433,7 @@ obj_from_addr(const void *addr) * non-NULL fini functions. */ static void -objlist_call_fini(Objlist *list) +objlist_call_fini(Objlist *list, int *lockstate) { Objlist_Entry *elm; char *saved_msg; @@ -1443,6 +1443,7 @@ objlist_call_fini(Objlist *list) * call into the dynamic linker and overwrite it. */ saved_msg = errmsg_save(); + wlock_release(rtld_bind_lock, *lockstate); STAILQ_FOREACH(elm, list, link) { if (elm->obj->refcount == 0) { dbg("calling fini function for %s at %p", elm->obj->path, @@ -1452,6 +1453,7 @@ objlist_call_fini(Objlist *list) call_initfini_pointer(elm->obj, elm->obj->fini); } } + *lockstate = wlock_acquire(rtld_bind_lock); errmsg_restore(saved_msg); } @@ -1461,7 +1463,7 @@ objlist_call_fini(Objlist *list) * functions. */ static void -objlist_call_init(Objlist *list) +objlist_call_init(Objlist *list, int *lockstate) { Objlist_Entry *elm; char *saved_msg; @@ -1471,6 +1473,7 @@ objlist_call_init(Objlist *list) * call into the dynamic linker and overwrite it. */ saved_msg = errmsg_save(); + wlock_release(rtld_bind_lock, *lockstate); STAILQ_FOREACH(elm, list, link) { dbg("calling init function for %s at %p", elm->obj->path, (void *)elm->obj->init); @@ -1478,6 +1481,7 @@ objlist_call_init(Objlist *list) elm->obj->path); call_initfini_pointer(elm->obj, elm->obj->init); } + *lockstate = wlock_acquire(rtld_bind_lock); errmsg_restore(saved_msg); } @@ -1638,15 +1642,18 @@ static void rtld_exit(void) { Obj_Entry *obj; + int lockstate; + lockstate = wlock_acquire(rtld_bind_lock); dbg("rtld_exit()"); /* Clear all the reference counts so the fini functions will be called. */ for (obj = obj_list; obj != NULL; obj = obj->next) obj->refcount = 0; - objlist_call_fini(&list_fini); + objlist_call_fini(&list_fini, &lockstate); /* No need to remove the items from the list, since we are exiting. */ if (!libmap_disable) lm_fini(); + wlock_release(rtld_bind_lock, lockstate); } static void * @@ -1760,11 +1767,9 @@ dlclose(void *handle) if (root->refcount == 0) { /* * The object is no longer referenced, so we must unload it. - * First, call the fini functions with no locks held. + * First, call the fini functions. */ - wlock_release(rtld_bind_lock, lockstate); - objlist_call_fini(&list_fini); - lockstate = wlock_acquire(rtld_bind_lock); + objlist_call_fini(&list_fini, &lockstate); objlist_remove_unref(&list_fini); /* Finish cleaning up the newly-unreferenced objects. */ @@ -1872,10 +1877,8 @@ dlopen(const char *name, int mode) name); GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL); - /* Call the init functions with no locks held. */ - wlock_release(rtld_bind_lock, lockstate); - objlist_call_init(&initlist); - lockstate = wlock_acquire(rtld_bind_lock); + /* Call the init functions. */ + objlist_call_init(&initlist, &lockstate); objlist_clear(&initlist); wlock_release(rtld_bind_lock, lockstate); return obj;