[v2] ld.so: Check for new cache format first and enhance corruption check

Message ID 87sgfcxzim.fsf@oldenburg2.str.redhat.com
State Committed
Headers
Series [v2] ld.so: Check for new cache format first and enhance corruption check |

Commit Message

Florian Weimer June 3, 2020, 9:35 a.m. UTC
  Now that ldconfig defaults to the new format (only), check for it
first.  Also apply the corruption check added in commit 2954daf00bb4d
("Add more checks for valid ld.so.cache file (bug 18093)") to the
new-format-only case.

Suggested-by: Josh Triplett <josh@joshtriplett.org>

---
 elf/dl-cache.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)
  

Comments

Florian Weimer June 15, 2020, 8:49 a.m. UTC | #1
* Florian Weimer via Libc-alpha:

> Now that ldconfig defaults to the new format (only), check for it
> first.  Also apply the corruption check added in commit 2954daf00bb4d
> ("Add more checks for valid ld.so.cache file (bug 18093)") to the
> new-format-only case.

I've pushed this, as the feedback for v1 already looked like approval.

Thanks,
Florian
  

Patch

diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index 3eedd9afcf..93d185e788 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -199,15 +199,25 @@  _dl_load_cache_lookup (const char *name)
 					       PROT_READ);
 
       /* We can handle three different cache file formats here:
+	 - only the new format
 	 - the old libc5/glibc2.0/2.1 format
 	 - the old format with the new format in it
-	 - 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
+      if (file != MAP_FAILED && cachesize > sizeof *cache_new
+	  && memcmp (file, CACHEMAGIC_VERSION_NEW,
+		     sizeof CACHEMAGIC_VERSION_NEW - 1) == 0
 	  /* Check for corruption, avoiding overflow.  */
-	  && ((cachesize - sizeof *cache) / sizeof (struct file_entry)
-	      >= ((struct cache_file *) file)->nlibs))
+	  && ((cachesize - sizeof *cache_new) / sizeof (struct file_entry_new)
+	      >= ((struct cache_file_new *) file)->nlibs))
+	{
+	  cache_new = file;
+	  cache = file;
+	}
+      else if (file != MAP_FAILED && cachesize > sizeof *cache
+	       && 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.  */
@@ -223,13 +233,6 @@  _dl_load_cache_lookup (const char *name)
 			 sizeof CACHEMAGIC_VERSION_NEW - 1) != 0)
 	    cache_new = (void *) -1;
 	}
-      else if (file != MAP_FAILED && cachesize > sizeof *cache_new
-	       && memcmp (file, CACHEMAGIC_VERSION_NEW,
-			  sizeof CACHEMAGIC_VERSION_NEW - 1) == 0)
-	{
-	  cache_new = file;
-	  cache = file;
-	}
       else
 	{
 	  if (file != MAP_FAILED)