* 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.
This commit is contained in:
Roland McGrath 2002-08-22 08:11:48 +00:00
parent 5015cde4c8
commit 4e20f1e215
2 changed files with 33 additions and 9 deletions

View File

@ -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.

View 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;