[patch] libstdc++/67747 Allocate space for dirent::d_name
Martin Sebor
msebor@gmail.com
Fri Oct 2 16:57:00 GMT 2015
On 10/02/2015 06:34 AM, Jonathan Wakely wrote:
> On 02/10/15 14:16 +0200, Florian Weimer wrote:
>> On 09/29/2015 01:37 PM, Jonathan Wakely wrote:
>>> POSIX says that dirent::d_name has an unspecified length, so calls to
>>> readdir_r must pass a buffer with enough trailing space for
>>> {NAME_MAX}+1 characters. I wasn't doing that, which works OK on
>>> GNU/Linux and BSD where d_name is a large array, but fails on Solaris
>>> 32-bit.
>>>
>>> This uses pathconf to get NAME_MAX and allocates a buffer.
>>
>> This still has a buffer overflow on certain file systems.
>>
>> You must not use readdir_r, it is deprecated and always insecure. We
>> should probably mark it as such in the glibc headers.
>
> OK, I'll just use readdir() then. The directory stream is private to
> the library type, so the only way to call readdir() concurrently on a
> single directory stream is to increment iterators concurrently, which
> is undefined anyway.
>
> So that will work as long as readdir() doesn't use a global static
> buffer shared between streams, i.e. it meets the POSIX requirement
> that "They shall not be affected by a call to readdir() on a different
> directory stream." I don't know if mingw meets that, but there is lots
> of work needed to make this stuff work in mingw.
Readdir isn't required to be thread-safe (it may reference global
data) so calling it in multiple threads even with a different dirp
argument is undefined. A thread-unsafe implementation can meet the
POSIX requirement and still access global data but without locking.
The Solaris implementation, for example, is explicitly documented
as thread unsafe.
Martin
More information about the Libstdc++
mailing list