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

Bug#456531: libc6: strerror_r() not thread-safe



Subject: libc6: strerror_r() not thread-safe
Package: libc6
Version: 2.7-4
Severity: important

        Hello,

strerror_r() crashes pseudo-randomly when multiple threads invoke it 
simultaneously. It appears the problem never occurs when using the C/POSIX 
locale, and seems to be gettext-related.

Test code attached.

Interestingly, I once had the crash with the first error message in C locale:

# ./a.out
Connection timed out
Erreur de segmentation
#

Then again, I also had this once:
# ./a.out
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Connexion terminée par expiration du délai d'attente
Erreur de segmentation
#

Could not reproduce under valgrind - still from gdb:

# gdb ./a.out
(...)
(gdb) run
(...)
Connexion terminée par
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x86bd0b90 (LWP 10614)]
0xb7e599d8 in strcmp () from /lib/i686/cmov/libc.so.6
(gdb) bt
#0  0xb7e599d8 in strcmp () from /lib/i686/cmov/libc.so.6
#1  0xb7e0d473 in _nl_find_msg () from /lib/i686/cmov/libc.so.6
#2  0xb7e0e122 in __dcigettext () from /lib/i686/cmov/libc.so.6
#3  0xb7e0ceb3 in dcgettext () from /lib/i686/cmov/libc.so.6
#4  0xb7e59ee9 in strerror_r () from /lib/i686/cmov/libc.so.6
#5  0xb7e27c9f in vfprintf () from /lib/i686/cmov/libc.so.6
#6  0xb7e4a874 in vsnprintf () from /lib/i686/cmov/libc.so.6
#7  0xb7e2f1d5 in snprintf () from /lib/i686/cmov/libc.so.6
#8  0x080485f0 in run ()
#9  0xb7f3a4fb in start_thread () from /lib/i686/cmov/libpthread.so.0
#10 0xb7ebe60e in clone () from /lib/i686/cmov/libc.so.6


-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (100, 'unstable'), (100, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.23.8 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libc6 depends on:
ii  libgcc1                       1:4.2.2-4  GCC support library

libc6 recommends no packages.

-- debconf information:
  glibc/restart-failed:
  glibc/restart-services:

-- 
Rémi Denis-Courmont
http://www.remlab.net/
#include <stdio.h>
#include <pthread.h>
#include <locale.h>
#include <libintl.h>
#include <errno.h>

#define NTH 100

static pthread_barrier_t *bp;

static void *run (void *dummy)
{
	char buf[256];

	(void)dummy;
	errno = ETIMEDOUT;

	pthread_barrier_wait (bp);
	for (;;)
	{
		snprintf (buf, sizeof (buf), "%m");
		puts (buf);
	}
}

int main (void)
{
	unsigned i;
	pthread_barrier_t barrier;
	pthread_t threads[NTH];

	setlocale (LC_ALL, "");
	bindtextdomain ("vlc", "/usr/share/locale");

	pthread_barrier_init (&barrier, NULL, NTH);
	bp = &barrier;

	for (i = 0; i < NTH; i++)
		pthread_create (threads + i, NULL, run, NULL);

	run (NULL);
	return 0;
}

Attachment: signature.asc
Description: This is a digitally signed message part.


Reply to: