This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix locking issue in newlocale


On Fri, Jul 16, 2004 at 11:23:55AM +0200, Paolo Carlini wrote:
> > And in fact, in one crash I have analysed, it looks as if glibc-internal
> > data structures are corrupted.

Indeed, you're right.
I have been able to reproduce this with on 4way x86-64:

#define _GNU_SOURCE
#include <locale.h>
#include <pthread.h>

const char *locales[] = { "de_DE.ISO-8859-1", "en_US.ISO-8859-1" };

void *
tf (void *arg)
{
  int i;
  for (i = 0; i < 100000; ++i)
    {
      locale_t l = newlocale (LC_ALL_MASK, locales[i & 1], NULL);
      freelocale (l);
    }
}

void *
tf2 (void *arg)
{
  int i;
  for (i = 0; i < 100000; ++i)
    setlocale (LC_ALL, locales[(i % 27) & 1]);
}

int
main (void)
{
  pthread_t p[10];
  int i;
  for (i = 0; i < 10; ++i)
    pthread_create (&p[i], NULL, i % 2 ? tf : tf2, NULL);
  for (i = 0; i < 10; ++i)
    pthread_join (p[i], NULL);
  return 0;
}

(not every time, but with while /tmp/test; do :; done it always crashed
after a while).
With the patch below it doesn't crash (at least for the 15 minutes
I was running this test before stopping it).
duplocale/freelocale already use this lock.

2004-07-16  Jakub Jelinek  <jakub@redhat.com>

	* locale/newlocale.c: Include bits/libc-lock.h.
	(__libc_setlocale_lock): Extern decl.
	(__newlocale): Use it.
	Reported by Ulrich Weigand <Ulrich.Weigand@de.ibm.com>.

--- libc/locale/newlocale.c.jj	2004-07-16 09:33:23.000000000 -0400
+++ libc/locale/newlocale.c	2004-07-16 09:44:33.000000000 -0400
@@ -1,5 +1,6 @@
 /* Return a reference to locale information record.
-   Copyright (C) 1996,1997,1999,2000,2001,2002 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2004
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -19,6 +20,7 @@
    02111-1307 USA.  */
 
 #include <argz.h>
+#include <bits/libc-lock.h>
 #include <errno.h>
 #include <locale.h>
 #include <stdlib.h>
@@ -27,6 +29,10 @@
 #include "localeinfo.h"
 
 
+/* Lock for protecting global data.  */
+__libc_lock_define (extern , __libc_setlocale_lock attribute_hidden)
+
+
 /* Use this when we come along an error.  */
 #define ERROR_RETURN							      \
   do {									      \
@@ -154,6 +160,9 @@ __newlocale (int category_mask, const ch
 	ERROR_RETURN;
     }
 
+  /* Protect global data.  */
+  __libc_lock_lock (__libc_setlocale_lock);
+
   /* Now process all categories we are interested in.  */
   names_len = 0;
   for (cnt = 0; cnt < __LC_LAST; ++cnt)
@@ -171,6 +180,9 @@ __newlocale (int category_mask, const ch
 		    && result.__locales[cnt]->usage_count != UNDELETABLE)
 		  /* We can remove the data.  */
 		  _nl_remove_locale (cnt, result.__locales[cnt]);
+
+              /* Critical section left.  */
+              __libc_lock_unlock (__libc_setlocale_lock);
 	      return NULL;
 	    }
 
@@ -249,6 +261,9 @@ __newlocale (int category_mask, const ch
       free (base);
     }
 
+  /* Critical section left.  */
+  __libc_lock_unlock (__libc_setlocale_lock);
+
   /* Update the special members.  */
  update:
   {


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]