446cf2
commit e221c512c74ec42fd47b71de2981a475b38110a4
446cf2
Author: Florian Weimer <fweimer@redhat.com>
446cf2
Date:   Mon Jun 15 09:50:14 2020 +0200
446cf2
446cf2
    ld.so: Check for new cache format first and enhance corruption check
446cf2
    
446cf2
    Now that ldconfig defaults to the new format (only), check for it
446cf2
    first.  Also apply the corruption check added in commit 2954daf00bb4d
446cf2
    ("Add more checks for valid ld.so.cache file (bug 18093)") to the
446cf2
    new-format-only case.
446cf2
    
446cf2
    Suggested-by: Josh Triplett <josh@joshtriplett.org>
446cf2
446cf2
diff --git a/elf/dl-cache.c b/elf/dl-cache.c
446cf2
index 6dd99a35b9f97cfb..ef37ca18fa9fb6e0 100644
446cf2
--- a/elf/dl-cache.c
446cf2
+++ b/elf/dl-cache.c
446cf2
@@ -199,15 +199,25 @@ _dl_load_cache_lookup (const char *name)
446cf2
 					       PROT_READ);
446cf2
 
446cf2
       /* We can handle three different cache file formats here:
446cf2
+	 - only the new format
446cf2
 	 - the old libc5/glibc2.0/2.1 format
446cf2
 	 - the old format with the new format in it
446cf2
-	 - only the new format
446cf2
 	 The following checks if the cache contains any of these formats.  */
446cf2
-      if (file != MAP_FAILED && cachesize > sizeof *cache
446cf2
-	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0
446cf2
+      if (file != MAP_FAILED && cachesize > sizeof *cache_new
446cf2
+	  && memcmp (file, CACHEMAGIC_VERSION_NEW,
446cf2
+		     sizeof CACHEMAGIC_VERSION_NEW - 1) == 0
446cf2
 	  /* Check for corruption, avoiding overflow.  */
446cf2
-	  && ((cachesize - sizeof *cache) / sizeof (struct file_entry)
446cf2
-	      >= ((struct cache_file *) file)->nlibs))
446cf2
+	  && ((cachesize - sizeof *cache_new) / sizeof (struct file_entry_new)
446cf2
+	      >= ((struct cache_file_new *) file)->nlibs))
446cf2
+	{
446cf2
+	  cache_new = file;
446cf2
+	  cache = file;
446cf2
+	}
446cf2
+      else if (file != MAP_FAILED && cachesize > sizeof *cache
446cf2
+	       && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0
446cf2
+	       /* Check for corruption, avoiding overflow.  */
446cf2
+	       && ((cachesize - sizeof *cache) / sizeof (struct file_entry)
446cf2
+		   >= ((struct cache_file *) file)->nlibs))
446cf2
 	{
446cf2
 	  size_t offset;
446cf2
 	  /* Looks ok.  */
446cf2
@@ -223,13 +233,6 @@ _dl_load_cache_lookup (const char *name)
446cf2
 			 sizeof CACHEMAGIC_VERSION_NEW - 1) != 0)
446cf2
 	    cache_new = (void *) -1;
446cf2
 	}
446cf2
-      else if (file != MAP_FAILED && cachesize > sizeof *cache_new
446cf2
-	       && memcmp (file, CACHEMAGIC_VERSION_NEW,
446cf2
-			  sizeof CACHEMAGIC_VERSION_NEW - 1) == 0)
446cf2
-	{
446cf2
-	  cache_new = file;
446cf2
-	  cache = file;
446cf2
-	}
446cf2
       else
446cf2
 	{
446cf2
 	  if (file != MAP_FAILED)