aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--locale/loadarchive.c34
2 files changed, 33 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index ac29548..38cf493 100644
--- 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.
diff --git a/locale/loadarchive.c b/locale/loadarchive.c
index e32e8c7..d25334a 100644
--- a/locale/loadarchive.c
+++ b/locale/loadarchive.c
@@ -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;