libdl usage count wrapping

Kevin Day thekevinday at gmail.com
Thu Sep 25 21:11:01 UTC 2008


On Wed, Sep 24, 2008 at 10:15 AM, Vallevand, Mark K
<Mark.Vallevand at unisys.com> wrote:
> And, here's the patch I used to fix the memory leak.
>
> --- old/ldso/libdl/libdl.c      2008-09-17 08:42:34.000000000 -0500
> +++ uClibc/ldso/libdl/libdl.c   2008-09-16 15:14:44.000000000 -0500
> @@ -632,6 +632,13 @@
>                }
>        }
>        free(handle->init_fini.init_fini);
> +    while ( handle->next )
> +    {
> +        struct dyn_elf *t;
> +        t = handle->next->next;
> +        free ( handle->next );
> +        handle->next = t;
> +    }
>        free(handle);
>
>
>
> Regards.
> Mark K Vallevand

I've tried this patch on my system and problem persists.
Again, I am using uClibc 0.9.28.3 and that may mean additional
problems exist outside of this.
I also updated my tests to dlload libraries that are on my system and
then ran the program from within valgrind.
My tests are against a live system and I did not have debugging in
uClibc enabled (which I intend rebuild one that does)

My results:

 Call ... 6552/50000
opened 0
closed 0

 Call ... 6553/50000
opened 0
==1755== Jump to the invalid address stated on the next line
==1755==    at 0x4071870: ???
==1755==    by 0x80484DF: closelibs (stress-dlopen.c:42)
==1755==    by 0x8048566: main (stress-dlopen.c:59)
==1755==  Address 0x4071870 is not stack'd, malloc'd or (recently) free'd
==1755==
==1755== Process terminating with default action of signal 11 (SIGSEGV): dumping
 core
==1755==  Access not within mapped region at address 0x4071870
==1755==    at 0x4071870: ???
==1755==    by 0x80484DF: closelibs (stress-dlopen.c:42)
==1755==    by 0x8048566: main (stress-dlopen.c:59)
==1755==
==1755== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==1755== malloc/free: in use at exit: 332 bytes in 8 blocks.
==1755== malloc/free: 275,276 allocs, 275,268 frees, 15,906,926 bytes allocated.
==1755== For counts of detected errors, rerun with: -v
==1755== searching for pointers to 8 not-freed blocks.
==1755== checked 38,064 bytes.
==1755==
==1755==
==1755== 12 bytes in 1 blocks are still reachable in loss record 1 of 4
==1755==    at 0x40197C8: malloc (in /toolchain/lib/valgrind/x86-linux/vgpreload
_memcheck.so)
==1755==    by 0x401F1CB: dlopen (in /lib/libdl-0.9.28.so)
==1755==    by 0x8048467: openlibs (stress-dlopen.c:28)
==1755==    by 0x804854B: main (stress-dlopen.c:57)
==1755==
==1755==
==1755== 24 bytes in 1 blocks are still reachable in loss record 2 of 4
==1755==    at 0x40197C8: malloc (in /toolchain/lib/valgrind/x86-linux/vgpreload
_memcheck.so)
==1755==    by 0x401EF99: dlopen (in /lib/libdl-0.9.28.so)
==1755==    by 0x8048467: openlibs (stress-dlopen.c:28)
==1755==    by 0x804854B: main (stress-dlopen.c:57)
==1755==
==1755==
==1755== 24 bytes in 3 blocks are still reachable in loss record 3 of 4
==1755==    at 0x40197C8: malloc (in /toolchain/lib/valgrind/x86-linux/vgpreload
_memcheck.so)
==1755==    by 0x401F21D: dlopen (in /lib/libdl-0.9.28.so)
==1755==    by 0x8048467: openlibs (stress-dlopen.c:28)
==1755==    by 0x804854B: main (stress-dlopen.c:57)
==1755==
==1755==
==1755== 272 bytes in 3 blocks are still reachable in loss record 4 of 4
==1755==    at 0x40197C8: malloc (in /toolchain/lib/valgrind/x86-linux/vgpreload
_memcheck.so)
==1755==    by 0x40014D1: _dl_malloc (in /lib/ld-uClibc-0.9.28.so)
==1755==    by 0x400168C: _dl_add_elf_hash_table (in /lib/ld-uClibc-0.9.28.so)
==1755==    by 0x4002974: _dl_load_elf_shared_library (in /lib/ld-uClibc-0.9.28.
so)
==1755==    by 0x4002E25: _dl_load_shared_library (in /lib/ld-uClibc-0.9.28.so)
==1755==    by 0x401F130: dlopen (in /lib/libdl-0.9.28.so)
==1755==    by 0x8048467: openlibs (stress-dlopen.c:28)
==1755==    by 0x804854B: main (stress-dlopen.c:57)
==1755==
==1755== LEAK SUMMARY:
==1755==    definitely lost: 0 bytes in 0 blocks.
==1755==      possibly lost: 0 bytes in 0 blocks.
==1755==    still reachable: 332 bytes in 8 blocks.
==1755==         suppressed: 0 bytes in 0 blocks.
Segmentation fault



Interestingly enough, when I enable (partially incomplete) ssp
protection: -fstack-protector-all -lssp, the problem happens here:
 Call ... 7280/50000
opened 0
closed 0

 Call ... 7281/50000
opened 0
Segmentation fault (core dumped)

Using this particular executable with gdb, i get the following:

 Call ... 7280/50000
opened 0
closed 0

 Call ... 7281/50000
opened 0

Program received signal SIGSEGV, Segmentation fault.
0xb7ef3870 in free () from /lib/libc.so.0

As a quick fix, perhaps a free needs to be wrapped by an if: if
(variable) free(variable);

That leaves the real problem, which specific free is failing and then
why is 'whatever is being freed' unallocated.
Is this a double free, or was the address never allocated for some reason?

-- 
Kevin Day



More information about the uClibc mailing list