|
|
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)
|