This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi! Below are two possible solutions for a pretty old bug in localealias.c which is visible under ElectricFence: If the string_space pool is too small, it is realloced, but realloc does not guarantee it will return the same pointer as was passed to it, but we already stored many string pointers to the old pool into the map array. One fix I see is (assuming realloc usually will give the same address as seems is the case in the common usage of setlocale in glibc, otherwise this bug would have been noticed far before) in P2, basically we check if the address changed and in the unlikely case that it changed we adjust the so far created map[] entries. The other fix is killing the realloc and replacing it with malloc - the string pool does not have to be contiguous. I keep a linked list in the first sizeof(char *) bytes of string pools so that they can be freed by free_mem. This has the disadvantage of slightly higher overhead if realloc would give the same address (at least because now we have to call free more times) but big advantage if it would not (as there is no realloc, it does not have to copy those thousands of bytes again and again, plus we don't have to fix map[] entries). Neither of these was tested, if you pick one solution you like, I'll test it out. Jakub
2000-10-10 Jakub Jelinek <jakub@redhat.com> * intl/localealias.c (read_alias_file): Don't realloc string_space, instead build a chain of string spaces. (free_mem): And free them as chain as well. --- libc/intl/localealias.c.jj Mon May 8 14:30:44 2000 +++ libc/intl/localealias.c Tue Oct 10 23:00:55 2000 @@ -342,17 +342,19 @@ read_alias_file (fname, fname_len) if (string_space_act + alias_len + value_len > string_space_max) { /* Increase size of memory pool. */ - size_t new_size = (string_space_max - + (alias_len + value_len > 1024 - ? alias_len + value_len : 1024)); - char *new_pool = (char *) realloc (string_space, new_size); + size_t size = (alias_len + value_len + sizeof (char *) > 1024 + ? alias_len + value_len + sizeof (char *) + : 1024)); + char *new_pool = (char *) malloc (size); if (new_pool == NULL) { FREE_BLOCKS (block_list); return added; } + *(char **) new_pool = string_space; + string_space_act = sizeof (char *); string_space = new_pool; - string_space_max = new_size; + string_space_max = size; } map[nmap].alias = memcpy (&string_space[string_space_act], @@ -405,8 +407,12 @@ extend_alias_table () static void __attribute__ ((unused)) free_mem (void) { - if (string_space != NULL) - free (string_space); + while (string_space) + { + char *next = *(char **) string_space; + free (string_space); + string_space = next; + } if (map != NULL) free (map); }
2000-10-10 Jakub Jelinek <jakub@redhat.com> * intl/localalias.c (read_alias_file): If realloc returned a different address than was passed to it, adjust map array's string pointers. --- libc/intl/localealias.c.jj Mon May 8 14:30:44 2000 +++ libc/intl/localealias.c Tue Oct 10 22:47:39 2000 @@ -351,6 +351,18 @@ read_alias_file (fname, fname_len) FREE_BLOCKS (block_list); return added; } + + if (string_space != new_pool) + { + size_t i; + + for (i = 0; i < nmap; i++) + { + map[i].alias += new_pool - string_space; + map[i].value += new_pool - string_space; + } + } + string_space = new_pool; string_space_max = new_size; }
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |