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 loadlocale


Hi!

For some locales, setlocale (well, _nl_load_locale_from_archive)
enters an endless loop, in the case I was debugging
there was just headmap in the chain, from 0, len 2MB and a range wanted an
area which started at ~ 1.5MB and was ~ 800KB long.
The following patch fixes this. If ranges[cnt] starts before end of mapped
area but ends after it, we need to mmap a new area, but need to insert it
after mapped, not before, so that the chain is sorted (the endless loop
was because list insertion is not prepared to insert before headmap).
The other case where the change in first hunk changes old behaviour is if
ranges[cnt] starts before mapped starts and ends after mmaped ends, but
that really shouldn't happen, ranges[cnt] represents a single locale mapping
and _nl_load_locale_from_archive shouldn't ever mmap only some middle part
of some locale file in.
The second hunk is just a cleanup, both from and len are integers, so there
is no point to cast it to char pointer.
The third chunk tries to ensure that each range is fully mapped just once,
not several times.

2002-08-20  Jakub Jelinek  <jakub@redhat.com>

	* locale/loadarchive.c (_nl_load_locale_from_archive): Handle
	partially overlapping mappings.  Remove unneeded (char *) casts.
	Never allow duplication of ranges in mapped areas.

--- libc/locale/loadarchive.c.jj	2002-08-20 11:07:46.000000000 +0200
+++ libc/locale/loadarchive.c	2002-08-20 13:39:18.000000000 +0200
@@ -327,7 +327,8 @@ _nl_load_locale_from_archive (int catego
 
 	  /* Determine whether the appropriate page is already mapped.  */
 	  while (mapped != NULL
-		 && mapped->from + mapped->len <= ranges[cnt].from)
+		 && (mapped->from + mapped->len
+		     <= ranges[cnt].from + ranges[cnt].len))
 	    {
 	      last = mapped;
 	      mapped = mapped->next;
@@ -336,8 +337,8 @@ _nl_load_locale_from_archive (int catego
 	  /* Do we have a match?  */
 	  if (mapped != NULL
 	      && mapped->from <= ranges[cnt].from
-	      && ((char *) ranges[cnt].from + ranges[cnt].len
-		  <= (char *) mapped->from + mapped->len))
+	      && (ranges[cnt].from + ranges[cnt].len
+		  <= mapped->from + mapped->len))
 	    {
 	      /* Yep, already loaded.  */
 	      results[ranges[cnt].category].addr = ((char *) mapped->ptr
@@ -356,6 +357,9 @@ _nl_load_locale_from_archive (int catego
 	  upper = cnt;
 	  do
 	    {
+	      /* If a range is already mmaped in, stop.  */
+	      if (mapped != NULL && ranges[upper].from >= mapped->from)
+		break;
 	      to = ((ranges[upper].from + ranges[upper].len + ps - 1)
 		    & ~(ps - 1));
 	      ++upper;

	Jakub


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