2017-12-18 Dmitry V. Levin [BZ #22627] * elf/dl-load.c (_dl_init_paths): Remove _dl_dst_substitute preparatory code and invocation. 2017-12-14 Florian Weimer [BZ #22607] CVE-2017-1000409 * elf/dl-load.c (_dl_init_paths): Compute number of components in the expanded path string. 2017-12-14 Florian Weimer [BZ #22606] CVE-2017-1000408 * elf/dl-load.c (system_dirs): Update comment. (_dl_init_paths): Use nsystem_dirs_len to compute the array size. Index: glibc-2.26/elf/dl-load.c =================================================================== --- glibc-2.26.orig/elf/dl-load.c +++ glibc-2.26/elf/dl-load.c @@ -103,7 +103,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; @@ -688,9 +690,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"); @@ -776,37 +777,14 @@ _dl_init_paths (const char *llp) if (llp != NULL && *llp != '\0') { - size_t nllp; - const char *cp = llp; - char *llp_tmp; - -#ifdef SHARED - /* Expand DSTs. */ - size_t cnt = DL_DST_COUNT (llp, 1); - if (__glibc_likely (cnt == 0)) - llp_tmp = strdupa (llp); - else - { - /* Determine the length of the substituted string. */ - size_t total = DL_DST_REQUIRED (l, llp, strlen (llp), cnt); - - /* Allocate the necessary memory. */ - llp_tmp = (char *) alloca (total + 1); - llp_tmp = _dl_dst_substitute (l, llp, llp_tmp, 1); - } -#else - llp_tmp = strdupa (llp); -#endif + char *llp_tmp = strdupa (llp); /* Decompose the LD_LIBRARY_PATH contents. First determine how many elements it has. */ - nllp = 1; - while (*cp) - { - if (*cp == ':' || *cp == ';') - ++nllp; - ++cp; - } + size_t nllp = 1; + for (const char *cp = llp_tmp; *cp != '\0'; ++cp) + if (*cp == ':' || *cp == ';') + ++nllp; env_path_list.dirs = (struct r_search_path_elem **) malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));