This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
dcigettext.c has a very clear use-after-free problem which can result in a user process getting a segfault or other error.
newmem = (transmem_block_t *) realloc (transmem_list, freemem_size); # ifdef _LIBC if (newmem != NULL) transmem_list = transmem_list->next; else { struct transmem_list *old = transmem_list;
transmem_list = transmem_list->next; free (old); } # endif
If the call to realloc requires transmem_list's memory to be moved, then the prior pointer is free'd. Most of the time this doesn't cause a noticeable problem because the memory is still mapped and the dereference in transmem_list->next shortly after the realloc call works fine (this is still wrong obviously).
However, if transmem_list was allocated by mmap (because it was large), when the original pointer is free'd as a result of the realloc call, the old memory gets ummapped. With the memory now unmapped, the transmem_list->next dereference of the old pointer fails with a segfault.
I don't have a good testcase -- the one provided to me hasn't tripped in about 12 hours of running or in shorter runs with differing values of M_MMAP_THRESHOLD and may contain confidential information. Hopefully the analysis above is clear enough to show this code is clearly broken.
Attachment:
P
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |