From nobody@FreeBSD.org  Tue Sep  3 19:17:38 2002
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 1968737B400
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  3 Sep 2002 19:17:38 -0700 (PDT)
Received: from www.freebsd.org (www.FreeBSD.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id B090F43E42
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  3 Sep 2002 19:17:37 -0700 (PDT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.4/8.12.4) with ESMTP id g842HbOT078577
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 3 Sep 2002 19:17:37 -0700 (PDT)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.4/8.12.4/Submit) id g842Hb67078576;
	Tue, 3 Sep 2002 19:17:37 -0700 (PDT)
Message-Id: <200209040217.g842Hb67078576@www.freebsd.org>
Date: Tue, 3 Sep 2002 19:17:37 -0700 (PDT)
From: Eric Albert <ejalbert@cs.stanford.edu>
To: freebsd-gnats-submit@FreeBSD.org
Subject: dlclose for a module loaded with RTLD_GLOBAL can access freed memory and crash
X-Send-Pr-Version: www-1.0

>Number:         42397
>Category:       bin
>Synopsis:       dlclose for a module loaded with RTLD_GLOBAL can access freed memory and crash
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kan
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Sep 03 19:20:01 PDT 2002
>Closed-Date:    Sun Jun 22 11:15:22 PDT 2003
>Last-Modified:  Sun Jun 22 11:15:22 PDT 2003
>Originator:     Eric Albert
>Release:        4.5
>Organization:
>Environment:
FreeBSD ithilien.qualarius.org 4.5-RELEASE FreeBSD 4.5-RELEASE #0: Mon Jan 28 14:31:56 GMT 2002   murray@builder.freebsdmall.com:/usr/src/sys/compile/GENERIC i386
>Description:
Consider two modules, A and B, where A links against B (B is in A's DAG). If both A and B are loaded via dlopen with the RTLD_GLOBAL flag, then B is unloaded via dlclose, when A is unloaded via dlclose B will not be removed from the list of global libraries. Any future symbol lookups in the application -- any standard function call inside or between a shared object -- can crash.

Specifically, in unload_object in src/libexec/rtld-elf/rtld.c, root is removed from list_global. Any object in root's DAG whose refcount drops to 0 is freed, but isn't removed from list_global. Any future reference to list_global will access freed memory if any one of those objects in root's DAG was loaded with RTLD_GLOBAL.
>How-To-Repeat:
Detecting the problem is dependent on the system's behavior when accessing freed memory, so it isn't easy to demonstrate the issue. It's easy to describe how to see it via code inspection, though:

Shared library A links against B.
In the application, A is loaded via dl_open(/path/to/A, RTLD_GLOBAL). This inserts A into the global list, with B in its DAG.
B is loaded via dl_open(/path/to/B, RTLD_GLOBAL). This modifies the refcount on B and inserts B into the global list (if the first step didn't do that; I'm not sure).
B is unloaded via dl_close. B's refcount drops to 1, and nothing is unloaded.
A is unloaded via dl_close. A's refcount drops to 0. A is removed from the global list. B's refcount drops to 0. In unload_object in src/libexec/rtld-elf/rtld.c, B's underlying data structure is freed, but B is not removed from the global list.
The application calls additional functions in other libraries, prompting a symbol lookup. Since B is still in the global list, access to B's element in that list can cause a crash.
>Fix:
[Not tested]

Take the objlist_remove(&list_global, root) line in unload_object and copy it inside the while loop in that function, to be called with obj instead of root if obj->refcount == 0.
>Release-Note:
>Audit-Trail:

From: Sergey Svishchev <svs@ropnet.ru>
To: freebsd-gnats-submit@FreeBSD.org
Cc: ejalbert@cs.stanford.edu
Subject: Re: bin/42397: dlclose for a module loaded with RTLD_GLOBAL can access freed memory and crash
Date: Tue, 6 May 2003 17:26:53 +0400

 This might be fixed by revision 1.72 of src/libexec/rtld-elf/rtld.c
 (MFCd in 1.43.2.15)
 
 -- 
 Sergey Svishchev
Responsible-Changed-From-To: freebsd-bugs->kan 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Sun Jun 22 10:53:37 PDT 2003 
Responsible-Changed-Why:  
Alexander, supposedly the bug was fixed in rev. 1.72 
src/libexec/rtld-elf/rtld.c.  Could you please confirm that? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=42397 
State-Changed-From-To: open->closed 
State-Changed-By: kan 
State-Changed-When: Sun Jun 22 11:14:43 PDT 2003 
State-Changed-Why:  
Fixed. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=42397 
>Unformatted:
