* locale/loadarchive.c (_nl_load_locale_from_archive): Check max file
authorRoland McGrath <roland@gnu.org>
Thu, 22 Aug 2002 08:11:48 +0000 (08:11 +0000)
committerRoland McGrath <roland@gnu.org>
Thu, 22 Aug 2002 08:11:48 +0000 (08:11 +0000)
position indicated by locrectab against file bounds before rounding to
page size.  In mapping loop, always set TO before breaking out of
contiguous range coalescing loop.

* locale/loadarchive.c (_nl_load_locale_from_archive): Use MAP_PRIVATE
(or MAP_COPY if available) instead of MAP_SHARED.

ChangeLog
locale/loadarchive.c

index ac29548..38cf493 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2002-08-22  Roland McGrath  <roland@redhat.com>
 
+       * locale/loadarchive.c (_nl_load_locale_from_archive): Check max file
+       position indicated by locrectab against file bounds before rounding to
+       page size.  In mapping loop, always set TO before breaking out of
+       contiguous range coalescing loop.
+
+       * locale/loadarchive.c (_nl_load_locale_from_archive): Use MAP_PRIVATE
+       (or MAP_COPY if available) instead of MAP_SHARED.
+
        * scripts/firstversions.awk: When encountering a version newer than
        the specified earliest version, be sure to emit the specified earliest
        version first if any renaming of an older version to that has been.
index e32e8c7..d25334a 100644 (file)
@@ -45,6 +45,19 @@ static const char archfname[] = LOCALEDIR "/locale-archive";
    cover the header plus the initial locale.  */
 #define ARCHIVE_MAPPING_WINDOW (2 * 1024 * 1024)
 
+#ifndef MAP_COPY
+/* This is not quite as good as MAP_COPY since unexamined pages
+   can change out from under us and give us inconsistent data.
+   But we rely on the user not to diddle the system's live archive.
+   Even though we only ever use PROT_READ, using MAP_SHARED would
+   not give the system sufficient freedom to e.g. let the on disk
+   file go away because it doesn't know we won't call mprotect later.  */
+# define MAP_COPY MAP_PRIVATE
+#endif
+#ifndef MAP_FILE
+ /* Some systems do not have this flag; it is superfluous.  */
+# define MAP_FILE 0
+#endif
 
 /* Record of contiguous pages already mapped from the locale archive.  */
 struct archmapped
@@ -208,7 +221,7 @@ _nl_load_locale_from_archive (int category, const char **namep)
       mapsize = (sizeof (void *) > 4 ? archive_stat.st_size
                 : MIN (archive_stat.st_size, ARCHIVE_MAPPING_WINDOW));
 
-      result = __mmap64 (NULL, mapsize, PROT_READ, MAP_SHARED, fd, 0);
+      result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY, fd, 0);
       if (result == MAP_FAILED)
        goto close_and_out;
 
@@ -226,7 +239,8 @@ _nl_load_locale_from_archive (int category, const char **namep)
          /* Freakishly long header.  */
          /* XXX could use mremap when available */
          mapsize = (headsize + ps - 1) & ~(ps - 1);
-         result = __mmap64 (NULL, mapsize, PROT_READ, MAP_SHARED, fd, 0);
+         result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY,
+                            fd, 0);
          if (result == MAP_FAILED)
            goto close_and_out;
        }
@@ -357,20 +371,21 @@ _nl_load_locale_from_archive (int category, const char **namep)
          upper = cnt;
          do
            {
+             to = ranges[upper].from + ranges[upper].len;
+             if (to > archive_stat.st_size)
+               /* The archive locrectab contains bogus offsets.  */
+               return NULL;
+             to = (to + ps - 1) & ~(ps - 1);
+
              /* 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;
            }
          /* Loop while still in contiguous pages. */
          while (upper < nranges && ranges[upper].from < to + ps);
 
-         if (to > archive_stat.st_size)
-           /* The archive locrectab contains bogus offsets.  */
-           return NULL;
-
          /* Open the file if it hasn't happened yet.  */
          if (fd == -1)
            {
@@ -391,7 +406,8 @@ _nl_load_locale_from_archive (int category, const char **namep)
            }
 
          /* Map the range from the archive.  */
-         addr = __mmap64 (NULL, to - from, PROT_READ, MAP_SHARED, fd, from);
+         addr = __mmap64 (NULL, to - from, PROT_READ, MAP_FILE|MAP_COPY,
+                          fd, from);
          if (addr == MAP_FAILED)
            return NULL;