aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2015-03-11 21:03:50 -0400
committerCarlos O'Donell <carlos@systemhalted.org>2015-03-11 21:07:32 -0400
commit6a1cf708dd5681b517744d6d4fac02e4e4a0aa2e (patch)
treea965b2d1be84995f55dbfdeb479b4a2b74f1ec69
parenta2d4cf72c0ab07d4e58b42c01ac3ed2b95ca8d9b (diff)
downloadglibc-6a1cf708dd5681b517744d6d4fac02e4e4a0aa2e.tar
glibc-6a1cf708dd5681b517744d6d4fac02e4e4a0aa2e.tar.gz
glibc-6a1cf708dd5681b517744d6d4fac02e4e4a0aa2e.tar.bz2
glibc-6a1cf708dd5681b517744d6d4fac02e4e4a0aa2e.zip
Fix ldconfig segmentation fault with corrupted cache (Bug 18093).
ldconfig is using an aux-cache to speed up the ld.so.cache update. It is read by mmaping the file to a structure which contains data offsets used as pointers. As they are not checked, it is not hard to get ldconfig to segfault with a corrupted file. This happens for instance if the file is truncated, which is common following a filesystem check following a system crash. This can be reproduced for example by truncating the file to roughly half of it's size. There is already some code in elf/cache.c (load_aux_cache) to check for a corrupted aux cache, but it happens to be broken and not enough. The test (aux_cache->nlibs >= aux_cache_size) compares the number of libs entry with the cache size. It's a non sense, as it basically assumes that each library entry is a 1 byte... Instead this commit computes the theoretical cache size using the headers and compares it to the real size.
-rw-r--r--ChangeLog6
-rw-r--r--NEWS2
-rw-r--r--elf/cache.c4
3 files changed, 10 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 736007961f..f12516b9a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-11 Aurelien Jarno <aurelien@aurel32.net>
+
+ [BZ #18093]
+ * elf/cache.c (load_aux_cache): Regenerate the cache if it has
+ the wrong size.
+
2015-03-11 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #18043]
diff --git a/NEWS b/NEWS
index 1cee779d76..6568085333 100644
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ Version 2.22
17792, 17836, 17912, 17916, 17932, 17944, 17949, 17964, 17965, 17967,
17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029,
18030, 18032, 18036, 18038, 18039, 18042, 18043, 18046, 18047, 18068,
- 18104, 18110, 18111.
+ 18093, 18104, 18110, 18111.
* Character encoding and ctype tables were updated to Unicode 7.0.0, using
new generator scripts contributed by Pravin Satpute and Mike FABIAN (Red
diff --git a/elf/cache.c b/elf/cache.c
index 1732268a9f..bde7984924 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -698,7 +698,9 @@ load_aux_cache (const char *aux_cache_name)
if (aux_cache == MAP_FAILED
|| aux_cache_size < sizeof (struct aux_cache_file)
|| memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1)
- || aux_cache->nlibs >= aux_cache_size)
+ || aux_cache_size != (sizeof(struct aux_cache_file) +
+ aux_cache->nlibs * sizeof(struct aux_cache_file_entry) +
+ aux_cache->len_strings))
{
close (fd);
init_aux_cache ();