From 28aa53341abbc5843fc78f283c397d11d74a33db Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 14 Dec 2017 15:18:38 +0100 Subject: elf: Compute correct array size in _dl_init_paths [BZ #22606] (cherry picked from commit 8a0b17e48b83e933960dfeb8fa08b259f03f310e) --- ChangeLog | 8 ++++++++ NEWS | 5 +++++ elf/dl-load.c | 14 +++++++------- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6e648c310d..90e4444444 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2017-12-14 Florian Weimer + + [BZ #22606] + CVE-2017-1000408 + * elf/dl-load.c (system_dirs): Update comment. + (nsystem_dirs_len): Use array_length. + (_dl_init_paths): Use nsystem_dirs_len to compute the array size. + 2017-11-02 Florian Weimer Add array_length and array_end macros. diff --git a/NEWS b/NEWS index bc32643255..9de14ffba0 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,11 @@ Security related changes: without GLOB_NOESCAPE, could write past the end of a buffer while unescaping user names. Reported by Tim Rühsen. +* CVE-2017-1000408: Incorrect array size computation in _dl_init_paths leads + to the allocation of too much memory. (This is not a security bug per se, + it is mentioned here only because of the CVE assignment.) Reported by + Qualys. + The following bugs are resolved with this release: [20790] Fix rpcgen buffer overrun diff --git a/elf/dl-load.c b/elf/dl-load.c index c0d6249373..0d46c16ea7 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -103,7 +104,9 @@ static size_t ncapstr attribute_relro; static size_t max_capstrlen attribute_relro; -/* Get the generated information about the trusted directories. */ +/* Get the generated information about the trusted directories. Use + an array of concatenated strings to avoid relocations. See + gen-trusted-dirs.awk. */ #include "trusted-dirs.h" static const char system_dirs[] = SYSTEM_DIRS; @@ -111,9 +114,7 @@ static const size_t system_dirs_len[] = { SYSTEM_DIRS_LEN }; -#define nsystem_dirs_len \ - (sizeof (system_dirs_len) / sizeof (system_dirs_len[0])) - +#define nsystem_dirs_len array_length (system_dirs_len) static bool is_trusted_path (const char *path, size_t len) @@ -688,9 +689,8 @@ _dl_init_paths (const char *llp) + ncapstr * sizeof (enum r_dir_status)) / sizeof (struct r_search_path_elem)); - rtld_search_dirs.dirs[0] = (struct r_search_path_elem *) - malloc ((sizeof (system_dirs) / sizeof (system_dirs[0])) - * round_size * sizeof (struct r_search_path_elem)); + rtld_search_dirs.dirs[0] = malloc (nsystem_dirs_len * round_size + * sizeof (*rtld_search_dirs.dirs[0])); if (rtld_search_dirs.dirs[0] == NULL) { errstring = N_("cannot create cache for search path"); -- cgit 1.4.1