[41077] in bugtraq

home help back first fref pref prev next nref lref last post

Re: [Full-disclosure] Re: readdir_r considered harmful

daemon@ATHENA.MIT.EDU (Andrew Farmer)
Mon Nov 7 18:51:59 2005

In-Reply-To: <200511060900.jA690qDk001066@vaticaan.Holland.Sun.COM>
Mime-Version: 1.0 (Apple Message framework v746.2)
Content-Type: multipart/signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="Apple-Mail-2-546709937"
Message-Id: <B52D4580-FF15-4096-A2D1-C725C3B0F833@gmail.com>
Cc: Ulrich Drepper <drepper@gmail.com>,
        Ben Hutchings <ben@decadentplace.org.uk>, bugtraq@securityfocus.com
Content-Transfer-Encoding: 7bit
From: Andrew Farmer <andfarm@gmail.com>
Date: Sun, 6 Nov 2005 17:00:48 -0800
To: full-disclosure@lists.grok.org.uk


--Apple-Mail-2-546709937
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed

On 06 Nov 05, at 01:00, Casper.Dik@Sun.COM wrote:
>> Then you never really understood the implementation, seems.  Of  
>> course
>> all implementations keep the content of the directory as read with
>> getdents or so in the DIR descriptor.  But it is usually not the case
>> that the whole content fits into the buffer allocated.  One could, of
>> course, resize the buffer to fit the content of the directory read,
>> even if this means reserving hundreds or thousands of kBs.  But this
>> is not how most implementations work.
>>
>
> I don't see how that is relevant; the typical use of readdir() is  
> as follows:
>
> 	DIR *dirp = opendir(name);
>
> 	while ((dent = readdir(dirp)) != NULL) {
> 		...
> 	}
>
> 	closedir(dirp);
>
> Nothing other threads do with readdir() on different dirp's will  
> influence
> what "dent" points to.
>
> I have *never* seen a program where multiple threads read from a  
> single
> dirp; and I can't image the use.
>

In practice, you're correct. In theory, however, consider the  
following code
path.


> THREAD 1                          THREAD 2
> ------------------------------    ------------------------------
> DIR *d1 = opendir(dir1);
>                                   DIR *d2 = opendir(dir2);
> dent1 = readdir(dir1);
>                                   dent2 = readdir(dir2);
> use(dent1);
>

In most implementations, dent1 != dent2. HOWEVER, there is no  
guarantee that
they will not both point to the same statically allocated buffer, and  
some
implementations may do so. For example, this is why ctime_r exists:  
ctime
returns a pointer to a statically allocated buffer, and hence is not  
thread
safe.

You are correct, though, that the glibc implementation of readdir is
thread-safe, so readdir_r is unnecessary in all common situations.

--Apple-Mail-2-546709937
content-type: application/pgp-signature; x-mac-type=70674453;
	name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)

iD8DBQFDbqdBPa6RRaKl0ScRAjwiAKDrmWxQLpuxnqdlC7LW401ro2NNpQCfZBQ7
sSW/1yS3FZ0wZOOFOediJP8=
=744w
-----END PGP SIGNATURE-----

--Apple-Mail-2-546709937--

home help back first fref pref prev next nref lref last post