[PATCH 1/8] elf: Bound the tunable cache string table against the mapping size

Adhemerval Zanella <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
_dl_load_cache_tunables bounds each entry's string offsets against
[s_start, start + cache_new->len_strings], but len_strings is an
unvalidated 32-bit field from ld.so.cache and s_start/s_end were int.  A
corrupt cache with an oversized len_strings could make s_end exceed the
mapping (or overflow), letting an offset point outside the mmap; the
following strcmp/__strdup would then read unmapped memory.

Compute the offsets as size_t and clamp s_end to cachesize, matching how
the regular library lookup bounds string offsets against the mapping size.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 elf/dl-cache.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index d05afe27004..5d8d3cae908 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -17,6 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <assert.h>
+#include <intprops.h>
 #include <unistd.h>
 #include <ldsodefs.h>
 #include <sys/mman.h>
@@ -649,9 +650,16 @@ _dl_load_cache_tunables (const char **data)
       != (void *) & tec[count])
     return NULL;
 
-  /* Validate each entry.  */
-  int s_start = (const char *) (&cache_new->libs[cache_new->nlibs]) - *data;
-  int s_end = s_start + cache_new->len_strings;
+  /* Validate each entry.  The string table lies between the file entries
+     and the end of the mapping; clamp its end to CACHESIZE so that a bogus
+     len_strings cannot make an offset point outside the mapped file.  */
+  size_t s_start = (const char *) (&cache_new->libs[cache_new->nlibs]) - *data;
+  size_t s_end;
+  if (s_start >= cachesize
+      || INT_ADD_WRAPV (s_start, cache_new->len_strings, &s_end))
+    return NULL;
+  if (s_end > cachesize)
+    s_end = cachesize;
   for (i = 0; i < count; i ++)
     {
       if (thc->tunables[i].name_offset < s_start
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.