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