b1dca6
commit 2954daf00bb4dc27c69a48e6798d5960ea320741
b1dca6
Author: Andreas Schwab <schwab@suse.de>
b1dca6
Date:   Tue Oct 23 09:40:14 2018 +0200
b1dca6
b1dca6
    Add more checks for valid ld.so.cache file (bug 18093)
b1dca6
b1dca6
diff --git a/elf/cache.c b/elf/cache.c
b1dca6
index e63979da7d25560c..c4cd825c30e00e8e 100644
b1dca6
--- a/elf/cache.c
b1dca6
+++ b/elf/cache.c
b1dca6
@@ -199,6 +199,11 @@ print_cache (const char *cache_name)
b1dca6
     }
b1dca6
   else
b1dca6
     {
b1dca6
+      /* Check for corruption, avoiding overflow.  */
b1dca6
+      if ((cache_size - sizeof (struct cache_file)) / sizeof (struct file_entry)
b1dca6
+	  < cache->nlibs)
b1dca6
+	error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
b1dca6
+
b1dca6
       size_t offset = ALIGN_CACHE (sizeof (struct cache_file)
b1dca6
 				   + (cache->nlibs
b1dca6
 				      * sizeof (struct file_entry)));
b1dca6
diff --git a/elf/dl-cache.c b/elf/dl-cache.c
b1dca6
index 6ee5153ff9514872..6dd99a35b9f97cfb 100644
b1dca6
--- a/elf/dl-cache.c
b1dca6
+++ b/elf/dl-cache.c
b1dca6
@@ -204,7 +204,10 @@ _dl_load_cache_lookup (const char *name)
b1dca6
 	 - only the new format
b1dca6
 	 The following checks if the cache contains any of these formats.  */
b1dca6
       if (file != MAP_FAILED && cachesize > sizeof *cache
b1dca6
-	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0)
b1dca6
+	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0
b1dca6
+	  /* Check for corruption, avoiding overflow.  */
b1dca6
+	  && ((cachesize - sizeof *cache) / sizeof (struct file_entry)
b1dca6
+	      >= ((struct cache_file *) file)->nlibs))
b1dca6
 	{
b1dca6
 	  size_t offset;
b1dca6
 	  /* Looks ok.  */