From 043c65b3c0de3b507bd84a0abebaf0c0fbb74f9d Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 21 Jul 1998 12:16:02 +0000 Subject: [PATCH] Catch incorrect string indeces and empty input file. --- catgets/open_catalog.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/catgets/open_catalog.c b/catgets/open_catalog.c index c3f10ffe537..92f8f2e3406 100644 --- a/catgets/open_catalog.c +++ b/catgets/open_catalog.c @@ -18,6 +18,7 @@ Boston, MA 02111-1307, USA. */ #include +#include #include #include #include @@ -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; + } } -- 2.47.2