diff options
author | Andreas Schwab <schwab@suse.de> | 2018-10-23 09:40:14 +0200 |
---|---|---|
committer | Andreas Schwab <schwab@suse.de> | 2018-10-24 16:34:02 +0200 |
commit | 2954daf00bb4dc27c69a48e6798d5960ea320741 (patch) | |
tree | 1515d3e310cfb3fc2e2547bcaea0c0a8fb3cac01 | |
parent | a27a4f4721837a5fb36ace833764b06a64c5af1c (diff) | |
download | glibc-2954daf00bb4dc27c69a48e6798d5960ea320741.tar.gz glibc-2954daf00bb4dc27c69a48e6798d5960ea320741.tar.xz glibc-2954daf00bb4dc27c69a48e6798d5960ea320741.zip |
Add more checks for valid ld.so.cache file (bug 18093)
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | elf/cache.c | 5 | ||||
-rw-r--r-- | elf/dl-cache.c | 5 |
3 files changed, 16 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog index 9b44e8de76..d6c5be93c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2018-10-24 Andreas Schwab <schwab@suse.de> + + [BZ #18093] + * elf/dl-cache.c (_dl_load_cache_lookup): Check for truncated old + format cache. + * elf/cache.c (print_cache): Likewise. + 2018-10-24 Albert ARIBAUD <albert.aribaud@3adev.fr> * bits/timesize.h: New file. diff --git a/elf/cache.c b/elf/cache.c index e63979da7d..c4cd825c30 100644 --- a/elf/cache.c +++ b/elf/cache.c @@ -199,6 +199,11 @@ print_cache (const char *cache_name) } else { + /* Check for corruption, avoiding overflow. */ + if ((cache_size - sizeof (struct cache_file)) / sizeof (struct file_entry) + < cache->nlibs) + error (EXIT_FAILURE, 0, _("File is not a cache file.\n")); + size_t offset = ALIGN_CACHE (sizeof (struct cache_file) + (cache->nlibs * sizeof (struct file_entry))); diff --git a/elf/dl-cache.c b/elf/dl-cache.c index 6ee5153ff9..6dd99a35b9 100644 --- a/elf/dl-cache.c +++ b/elf/dl-cache.c @@ -204,7 +204,10 @@ _dl_load_cache_lookup (const char *name) - 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) + && 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. */ |