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


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

a localedef bug



Hi,

localedef opens its output files via creat(), which temporarily truncates the
file to length 0. But at the same time other processes have this file mmapped.
When they access the file's contents they get a bus error. I got such "Bus
error (core dumped)" from gdb and bash. The bash backtrace shows

#0  0x400d1cf4 in __strtol_internal (nptr=0x80c1f90 "500", endptr=0xbfffe640, 
    base=10, group=0) at ../sysdeps/generic/strtol.c:306
306       while (ISSPACE (*s))

This patch fixes the bug by calling unlink() before creat().


2001-06-04  Bruno Haible  <haible@clisp.cons.org>

	* locale/programs/locfile.c (write_locale_data): Before creat(),
	unlink the file, to avoid crashing the processes that mmap it. Change
	a double slash to a single slash. Free fname in case of error return.

--- glibc-20010430/locale/programs/locfile.c.bak	Mon Jun  4 21:09:42 2001
+++ glibc-20010430/locale/programs/locfile.c	Mon Jun  4 22:22:30 2001
@@ -338,30 +338,33 @@
      data.  This means we need to have a directory LC_MESSAGES in
      which we place the file under the name SYS_LC_MESSAGES.  */
   sprintf (fname, "%s%s", output_path, category);
+  fd = -2;
   if (strcmp (category, "LC_MESSAGES") == 0)
     {
       struct stat st;
 
       if (stat (fname, &st) < 0)
 	{
-	  if (mkdir (fname, 0777) < 0)
-	    fd = creat (fname, 0666);
-	  else
+	  if (mkdir (fname, 0777) >= 0)
 	    {
 	      fd = -1;
 	      errno = EISDIR;
 	    }
 	}
-      else if (S_ISREG (st.st_mode))
-	fd = creat (fname, 0666);
-      else
+      else if (!S_ISREG (st.st_mode))
 	{
 	  fd = -1;
 	  errno = EISDIR;
 	}
     }
-  else
-    fd = creat (fname, 0666);
+
+  /* Create the locale file with nlinks == 1; this avoids crashing processes
+     which currently use the locale.  */
+  if (fd == -2)
+    {
+      unlink (fname);
+      fd = creat (fname, 0666);
+    }
 
   if (fd == -1)
     {
@@ -369,7 +372,8 @@
 
       if (errno == EISDIR)
 	{
-	  sprintf (fname, "%1$s/%2$s/SYS_%2$s", output_path, category);
+	  sprintf (fname, "%1$s%2$s/SYS_%2$s", output_path, category);
+	  unlink (fname);
 	  fd = creat (fname, 0666);
 	  if (fd == -1)
 	    save_err = errno;
@@ -381,6 +385,7 @@
 	    error (0, save_err, _("\
 cannot open output file `%s' for category `%s'"),
 		   fname, category);
+	  free (fname);
 	  return;
 	}
     }


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