[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#443660: libc6: dgettext not thread-safe



Le Sunday 23 September 2007 12:15:31 Pierre Habouzit, vous avez écrit :
> On Sun, Sep 23, 2007 at 08:15:45AM +0000, Rémi Denis-Courmont wrote:
> > #include <stdio.h>
> > #include <pthread.h>
> > #include <locale.h>
> > #include <libintl.h>
> >
> > static void *run (void *dummy)
> > {
> >         (void)dummy;
> >
> >         for (;;)
> >                 printf ("Translation code: %s\n", dgettext("vlc", "C"));
> > }
> >
> > int main (void)
> > {
> >         unsigned i;
> >         setlocale (LC_ALL, "");
> >         bindtextdomain ("vlc", "/usr/share/locale");
> >
> >         pthread_t threads[300];
> >         for (i = 0; i < sizeof (threads) / sizeof (threads[0]); i++)
> >                 pthread_create (threads + i, NULL, run, NULL);
> >
> >         run (NULL);
> >         return 0;
> > }
> >
> > When the problem occurs under valgrind, it complains:
> >
> > ==3535== Thread 3:
> > ==3535== Invalid read of size 4
>
>   This is probably because of a speculative strcmp (libc sometimes reads
> outside the string because it knows it can).
>
> > ==3535==    at 0x4063F0B: _nl_find_msg (dcigettext.c:862)
> > ==3535==    by 0x4064A41: __dcigettext (dcigettext.c:639)
> > ==3535==    by 0x4063972: dcgettext (dcgettext.c:53)
> > ==3535==    by 0x406399F: dgettext (dgettext.c:54)
> > ==3535==    by 0x80484DD: run (in /home/remi/a.out)
> > ==3535==    by 0x402D2D2: start_thread (pthread_create.c:296)
> > ==3535==    by 0x41124ED: clone (in /usr/lib/debug/libc-2.6.1.so)
> >
> >
> > ==3535==  Address 0x418C91C is 0 bytes after a block of size 12 alloc'd
> > ==3535==    at 0x4024862: realloc (vg_replace_malloc.c:306)
> > ==3535==    by 0x4063FF1: _nl_find_msg (dcigettext.c:876)
> > ==3535==    by 0x4064A41: __dcigettext (dcigettext.c:639)
> > ==3535==    by 0x4063972: dcgettext (dcgettext.c:53)
> > ==3535==    by 0x406399F: dgettext (dgettext.c:54)
> > ==3535==    by 0x80484DD: run (in /home/remi/a.out)
> > ==3535==    by 0x402D2D2: start_thread (pthread_create.c:296)
> > ==3535==    by 0x41124ED: clone (in /usr/lib/debug/libc-2.6.1.so)
>
>   This one though looks fishy.

It's the same error! It only means that _nl_find_msg from dcigettext.c:862 
tries to read at an address right after the end of a realloc() done at line 
876 in the same file, as far as I understand.

After the above errors, I usually get this:

==29015== Invalid read of size 1
==29015==    at 0x40255DE: strcmp (mc_replace_strmem.c:341)
==29015==    by 0x4063F18: _nl_find_msg (dcigettext.c:862)
==29015==    by 0x4064A41: __dcigettext (dcigettext.c:639)
==29015==    by 0x4063972: dcgettext (dcgettext.c:53)
==29015==    by 0x406399F: dgettext (dgettext.c:54)
==29015==    by 0x80484DD: run (in /home/remi/a.out)
==29015==    by 0x402D2D2: start_thread (pthread_create.c:296)
==29015==    by 0x41124ED: clone (in /usr/lib/debug/libc-2.6.1.so)
==29015==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==29015==
==29015== Process terminating with default action of signal 11 (SIGSEGV)
==29015==  Access not within mapped region at address 0x0
==29015==    at 0x40255DE: strcmp (mc_replace_strmem.c:341)
==29015==    by 0x4063F18: _nl_find_msg (dcigettext.c:862)
==29015==    by 0x4064A41: __dcigettext (dcigettext.c:639)
==29015==    by 0x4063972: dcgettext (dcgettext.c:53)
==29015==    by 0x406399F: dgettext (dgettext.c:54)
==29015==    by 0x80484DD: run (in /home/remi/a.out)
==29015==    by 0x402D2D2: start_thread (pthread_create.c:296)
==29015==    by 0x41124ED: clone (in /usr/lib/debug/libc-2.6.1.so)

Looks like strcmp tries to compare with NULL.

-- 
Rémi Denis-Courmont
http://www.remlab.net/




Reply to: