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