about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2018-10-23 09:40:14 +0200
committerAndreas Schwab <schwab@suse.de>2018-10-24 16:34:02 +0200
commit2954daf00bb4dc27c69a48e6798d5960ea320741 (patch)
tree1515d3e310cfb3fc2e2547bcaea0c0a8fb3cac01
parenta27a4f4721837a5fb36ace833764b06a64c5af1c (diff)
downloadglibc-2954daf00bb4dc27c69a48e6798d5960ea320741.tar.gz
glibc-2954daf00bb4dc27c69a48e6798d5960ea320741.tar.xz
glibc-2954daf00bb4dc27c69a48e6798d5960ea320741.zip
Add more checks for valid ld.so.cache file (bug 18093)
-rw-r--r--ChangeLog7
-rw-r--r--elf/cache.c5
-rw-r--r--elf/dl-cache.c5
3 files changed, 16 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 9b44e8de76..d6c5be93c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-10-24  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #18093]
+	* elf/dl-cache.c (_dl_load_cache_lookup): Check for truncated old
+	format cache.
+	* elf/cache.c (print_cache): Likewise.
+
 2018-10-24  Albert ARIBAUD <albert.aribaud@3adev.fr>
 
 	* bits/timesize.h: New file.
diff --git a/elf/cache.c b/elf/cache.c
index e63979da7d..c4cd825c30 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -199,6 +199,11 @@ print_cache (const char *cache_name)
     }
   else
     {
+      /* Check for corruption, avoiding overflow.  */
+      if ((cache_size - sizeof (struct cache_file)) / sizeof (struct file_entry)
+	  < cache->nlibs)
+	error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
+
       size_t offset = ALIGN_CACHE (sizeof (struct cache_file)
 				   + (cache->nlibs
 				      * sizeof (struct file_entry)));
diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index 6ee5153ff9..6dd99a35b9 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -204,7 +204,10 @@ _dl_load_cache_lookup (const char *name)
 	 - only the new format
 	 The following checks if the cache contains any of these formats.  */
       if (file != MAP_FAILED && cachesize > sizeof *cache
-	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0)
+	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0
+	  /* Check for corruption, avoiding overflow.  */
+	  && ((cachesize - sizeof *cache) / sizeof (struct file_entry)
+	      >= ((struct cache_file *) file)->nlibs))
 	{
 	  size_t offset;
 	  /* Looks ok.  */