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

Re: Bug#310588: some programs segfault when run with belocs-locales-* installed



clone 310588 -1
reassign -1 libc6
tags -1 + patch
thanks

On Tue, May 24, 2005 at 03:57:48PM +0300, Eugeniy Meshcheryakov wrote:
> Package: belocs-locales-bin
> Version: 2.3.4-8
> Severity: important
> 
> Some programs segfault when run with belocs-locales-* packages
> installed. Examples include: gimp when run with Ukrainian locale (also
> Russian, Serbian, Japanese and others), mozilla-firefox with
> mozilla-firefox-locale-uk (crashes after selecting some menu entries),
> sort (see attached script, crashes when run in UTF-8 locale). These
> programs do not crash with locales package installed.

Many thanks to Eugeniy who spent hours during last week to help me
understand what's going wrong here.
The conclusion is that there is a bug in strxfrm_l.c.  I just filed
BZ#968 upstream.  The proposed patch is quite trivial, but I could
not test it.  It can be reviewed without knowing strxfrm_l.c internals,
the issue is that the variable in a decremental loop is unsigned and
checked by backw >= backw_stop whereas backw_stop may be 0.
I would be glad if you glibc guys could review and apply this patch.
Thanks

Denis
Index: string/strxfrm_l.c
===================================================================
RCS file: /cvs/glibc/libc/string/strxfrm_l.c,v
retrieving revision 1.4
diff -u -r1.4 strxfrm_l.c
--- string/strxfrm_l.c	14 Mar 2004 20:52:47 -0000	1.4
+++ string/strxfrm_l.c	23 May 2005 22:35:59 -0000
@@ -210,18 +210,19 @@
 		      /* Handle the pushed elements now.  */
 		      size_t backw;
 
-		      for (backw = idxcnt - 1; backw >= backw_stop; --backw)
+		      /* Take care of integer overflow if backw_stop is 0.  */
+		      for (backw = idxcnt; backw > backw_stop; --backw)
 			{
-			  len = weights[idxarr[backw]++];
+			  len = weights[idxarr[backw - 1]++];
 
 			  if (needed + len < n)
 			    while (len-- > 0)
-			      dest[needed++] = weights[idxarr[backw]++];
+			      dest[needed++] = weights[idxarr[backw - 1]++];
 			  else
 			    {
 				/* No more characters fit into the buffer.  */
 			      needed += len;
-			      idxarr[backw] += len;
+			      idxarr[backw - 1] += len;
 			    }
 			}
 
@@ -293,9 +294,10 @@
 		     /* Handle the pushed elements now.  */
 		      size_t backw;
 
-		      for (backw = idxcnt - 1; backw >= backw_stop; --backw)
+		      /* Take care of integer overflow if backw_stop is 0.  */
+		      for (backw = idxcnt; backw > backw_stop; --backw)
 			{
-			  len = weights[idxarr[backw]++];
+			  len = weights[idxarr[backw - 1]++];
 			  if (len != 0)
 			    {
 #ifdef WIDE_CHAR_VERSION
@@ -304,7 +306,7 @@
 				  dest[needed] = val;
 				  for (i = 0; i < len; ++i)
 				    dest[needed + 1 + i] =
-				      weights[idxarr[backw] + i];
+				      weights[idxarr[backw - 1] + i];
 				}
 			      needed += 1 + len;
 #else
@@ -315,11 +317,11 @@
 				    dest[needed + i] = buf[i];
 				  for (i = 0; i < len; ++i)
 				    dest[needed + buflen + i] =
-				      weights[idxarr[backw] + i];
+				      weights[idxarr[backw - 1] + i];
 				}
 			      needed += buflen + len;
 #endif
-			      idxarr[backw] += len;
+			      idxarr[backw - 1] += len;
 			      val = 1;
 			    }
 			  else

Reply to: