nonstrings in Glibc

Florian Weimer fweimer@redhat.com
Tue Nov 21 21:34:00 GMT 2017


On 11/21/2017 10:20 PM, Martin Sebor wrote:

>> For the variable length member, d_name in struct dirent is another
>> example.  For struct dirent and struct dirent_64, all uses which rely on
>> a fixed size of the d_name member should probably result in warnings.
> 
> I see two struct dirent in my Glibc build on x86_64: one in
> bits/dirent.h and another in sysdeps/unix/sysv/linux/bits/dirent.h.
> AFAICT, the first one is the one that's installed and the second
> one is used internally within Glibc.

No, both are installed, but the one in sysdeps overrides the top-level 
one (on Linux).

> Did I get that right?  Should
> one of these be annotated with attribute nonstring? (POSIX requires
> d_name to be nul-terminated and there are assumptions in Glibc that
> rely on it being so, such as the _D_EXACT_NAMLEN() macro, that
> trigger the non-string warning if I annotate the latter.)
> 
> Also, what exactly do you mean by "uses which rely on a fixed size
> of the d_name member?"  Something attribute nonstring could help
> with or something else/some other warning?

It's not really related to the nonstring attribute, except that it's 
valid for the array not to contain a null terminator in both cases.

These structs can be allocated as part of a larger object where the name 
field runs off the end of the struct sockaddr_un/struct dirent object. 
As a result, if you use

   strcpy (d2->d_name, d1->d_name)

to make a copy of the name, that can introduce a buffer overflow.  (We 
had this bug in glob.)

The C language does not have a good way to address this, but things have 
been this way for ages on Linux with glibc.

Thanks,
Florian



More information about the Libc-alpha mailing list