mirror of
git://sourceware.org/git/glibc.git
synced 2025-04-06 14:10:30 +08:00
Catch incorrect string indeces and empty input file.
This commit is contained in:
parent
afe6c68c2e
commit
043c65b3c0
@ -18,6 +18,7 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -38,6 +39,10 @@ __open_catalog (__nl_catd catalog, int with_path)
|
||||
int fd = -1;
|
||||
struct stat st;
|
||||
int swapping;
|
||||
size_t cnt;
|
||||
size_t max_offset;
|
||||
size_t tab_size;
|
||||
const char *lastp;
|
||||
|
||||
if (strchr (catalog->cat_name, '/') != NULL || !with_path)
|
||||
fd = open (catalog->cat_name, O_RDONLY);
|
||||
@ -161,13 +166,21 @@ __open_catalog (__nl_catd catalog, int with_path)
|
||||
}
|
||||
}
|
||||
|
||||
if (fd < 0 || __fstat (fd, &st) < 0 || !S_ISREG (st.st_mode))
|
||||
if (fd < 0 || __fstat (fd, &st) < 0)
|
||||
{
|
||||
if (fd != -1)
|
||||
__close (fd);
|
||||
catalog->status = nonexisting;
|
||||
return;
|
||||
}
|
||||
if (!S_ISREG (st.st_mode) || st.st_size < sizeof (struct catalog_obj))
|
||||
{
|
||||
/* `errno' is not set correctly but the file is not usable.
|
||||
Use an reasonable error value. */
|
||||
__set_errno (EINVAL);
|
||||
catalog->status = nonexisting;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef MAP_COPY
|
||||
/* Linux seems to lack read-only copy-on-write. */
|
||||
@ -231,7 +244,8 @@ __open_catalog (__nl_catd catalog, int with_path)
|
||||
swapping = 1;
|
||||
else
|
||||
{
|
||||
/* Illegal file. Free he resources and mark catalog as not
|
||||
invalid_file:
|
||||
/* Invalid file. Free he resources and mark catalog as not
|
||||
usable. */
|
||||
if (catalog->status == mmapped)
|
||||
__munmap ((void *) catalog->file_ptr, catalog->file_size);
|
||||
@ -264,4 +278,27 @@ __open_catalog (__nl_catd catalog, int with_path)
|
||||
catalog->strings =
|
||||
(const char *) &catalog->file_ptr->name_ptr[catalog->plane_size
|
||||
* catalog->plane_depth * 3 * 2];
|
||||
|
||||
/* Determine the largest string offset mentioned in the table. */
|
||||
max_offset = 0;
|
||||
tab_size = 3 * catalog->plane_size * catalog->plane_depth;
|
||||
for (cnt = 2; cnt < tab_size; cnt += 3)
|
||||
if (catalog->name_ptr[cnt] > max_offset)
|
||||
max_offset = catalog->name_ptr[cnt];
|
||||
|
||||
/* Now we can check whether the file is large enough to contain the
|
||||
tables it says it contains. */
|
||||
if (st.st_size <= (sizeof (struct catalog_obj) + 2 * tab_size + max_offset))
|
||||
/* The last string is not contained in the file. */
|
||||
goto invalid_file;
|
||||
|
||||
lastp = catalog->strings + max_offset;
|
||||
max_offset = (st.st_size
|
||||
- sizeof (struct catalog_obj) + 2 * tab_size + max_offset);
|
||||
while (*lastp != '\0')
|
||||
{
|
||||
if (--max_offset == 0)
|
||||
goto invalid_file;
|
||||
++lastp;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user