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