Summary: | _dl_get_origin leaks memory via executable link map. | ||
---|---|---|---|
Product: | glibc | Reporter: | H.J. Lu <hjl.tools> |
Component: | dynamic-link | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | carlos |
Priority: | P2 | Flags: | fweimer:
security-
|
Version: | 2.17 | ||
Target Milestone: | 2.27 | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
H.J. Lu
2012-10-07 21:28:57 UTC
(In reply to H.J. Lu from comment #0) > When elf/tst-leaks1 is run directly, there is a memory > leak in expand_dynamic_string_token, which sets l_origin > to malloced memory from _dl_get_origin. When dlopened > fails, l_origin isn't freed. This is not true. The test tst-leaks1 exercises calling dlopen with a $ORIGIN DST. This results in a theoretical leak: cat elf/tst-leaks1-mem.out Memory not freed: ----------------- Address Size Caller 0x0000000001d766c0 0x21 at 0x7fb1bd8bf4ab Or as seen via valgrind: ==27582== 33 bytes in 1 blocks are still reachable in loss record 1 of 1 ==27582== at 0x4C2CB6B: malloc (vg_replace_malloc.c:299) ==27582== by 0x40124AA: _dl_get_origin (dl-origin.c:50) ==27582== by 0x4007DB9: expand_dynamic_string_token (dl-load.c:382) ==27582== by 0x400899C: _dl_map_object (dl-load.c:2160) ==27582== by 0x4013020: dl_open_worker (dl-open.c:224) ==27582== by 0x5166F9B: _dl_catch_exception (dl-error-skeleton.c:198) ==27582== by 0x4012BD9: _dl_open (dl-open.c:594) ==27582== by 0x4E39EF5: dlopen_doit (dlopen.c:66) ==27582== by 0x5166F9B: _dl_catch_exception (dl-error-skeleton.c:198) ==27582== by 0x516700E: _dl_catch_error (dl-error-skeleton.c:217) ==27582== by 0x4E3A514: _dlerror_run (dlerror.c:162) ==27582== by 0x4E39F70: dlopen@@GLIBC_2.2.5 (dlopen.c:87) There is no real leak. The calling link map (the executable's link map) has it's l_origin expanded for future use as part of _dl_get_origin, and that results in the main executable link map having a N-byte allocation for l->l_origin that is never freed since the executable's link map is just a part of the process. On failure we *do not* want to free the result of l_origin because it was a costly computation that we can keep around. Why didn't this failure show up before? (In reply to Carlos O'Donell from comment #1) > > Why didn't this failure show up before? It showed when I added and used --enable-hardcoded-path-in-tests. This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU C Library master sources". The branch, master has been updated via 93930ea9351c0c4a239e3dcb83f1398cce4e4d43 (commit) from 9d7a3741c9e59eba87fb3ca6b9f979befce07826 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=93930ea9351c0c4a239e3dcb83f1398cce4e4d43 commit 93930ea9351c0c4a239e3dcb83f1398cce4e4d43 Author: Carlos O'Donell <carlos@redhat.com> Date: Tue Dec 12 20:35:05 2017 -0800 Fix tst-leaks1 (bug 14681) The test tst-leaks1 exercises calling dlopen with a $ORIGIN DST. This results in a theoretical leak e.g. Memory not freed: ----------------- Address Size Caller 0x0000000001d766c0 0x21 at 0x7fb1bd8bf4ab Or as seen via valgrind: ==27582== 33 bytes in 1 blocks are still reachable in loss record 1 of 1 ==27582== at 0x4C2CB6B: malloc (vg_replace_malloc.c:299) ==27582== by 0x40124AA: _dl_get_origin (dl-origin.c:50) ==27582== by 0x4007DB9: expand_dynamic_string_token (dl-load.c:382) ==27582== by 0x400899C: _dl_map_object (dl-load.c:2160) ==27582== by 0x4013020: dl_open_worker (dl-open.c:224) ==27582== by 0x5166F9B: _dl_catch_exception (dl-error-skeleton.c:198) ==27582== by 0x4012BD9: _dl_open (dl-open.c:594) ==27582== by 0x4E39EF5: dlopen_doit (dlopen.c:66) ==27582== by 0x5166F9B: _dl_catch_exception (dl-error-skeleton.c:198) ==27582== by 0x516700E: _dl_catch_error (dl-error-skeleton.c:217) ==27582== by 0x4E3A514: _dlerror_run (dlerror.c:162) ==27582== by 0x4E39F70: dlopen@@GLIBC_2.2.5 (dlopen.c:87) There is no real leak. The calling link map (the executable's link map) has it's l_origin expanded for future use as part of _dl_get_origin, and that results in the main executable link map having a N-byte allocation for l->l_origin that is never freed since the executable's link map is just a part of the process. To take this into account we do one dlopen with $ORIGIN before calling mtrace to force the initialization of the executable link map. Signed-off-by: Carlos O'Donell <carlos@redhat.com> ----------------------------------------------------------------------- Summary of changes: ChangeLog | 6 ++++++ elf/tst-leaks1.c | 21 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) Fixed in 2.27. |