From Bugzilla Helper: User-Agent: Mozilla/5.0 Galeon/1.2.7 (X11; Linux i686; U;) Gecko/20030131 Description of problem: Trying to debug FreeTDS library glibc seem to crash using ElectricFence as memory debugger. iconv seem to access to freed memory. I simplyfied my test program until I get a simple C program that depend only on glibc and still crash. Version-Release number of selected component (if applicable): glibc-2.3.2-27.9 How reproducible: Always Steps to Reproduce: 1. Write a C file as #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <iconv.h> #include <pwd.h> #include <string.h> static char * tds_get_homedir2(void) { struct passwd *pw, bpw; char buf[1024]; if (getpwuid_r(getuid(), &bpw, buf, sizeof(buf), &pw)) return NULL; return strdup(pw->pw_dir); } int main(int argc, char **argv) { iconv_t cd; void *c = malloc(100); printf("line %d\n", __LINE__); tds_get_homedir2(); cd = iconv_open("ISO-8859-1", "UTF-8"); iconv_close(cd); printf("line %d\n", __LINE__); free(c); printf("line %d\n", __LINE__); return 0; } 2. compile with (you must have ElectricFence installed) gcc -O2 -Wall -lefence -o iconvbug iconvbug.c 3. enable freed memory protection export EF_PROTECT_FREE=1 4. launch it ./iconvbug Actual Results: A core is reported Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <bruce> line 28 line 35 line 37 Segmentation fault (core dumped) gdb ./iconvbug core.3681 (gdb) bt #0 0x40031fb4 in gconv () from /usr/lib/gconv/ISO8859-1.so #1 0x42029d40 in exit () from /lib/tls/libc.so.6 #2 0x42015708 in __libc_start_main () from /lib/tls/libc.so.6 Expected Results: It should not crash Additional info: Commenting iconv calls or getpwuid_r call program do not crash.
This is no glibc problem, there is something wrong with ElectricFence. Not surprising actually, a lot of the functionality it implements is fragile at best. What happens is that it somehow gets confused about the blocks it allocated. This is an excerpt from the strace run: mmap2(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf45b000 mprotect(0xbf45c000, 1044480, PROT_NONE) = 0 mprotect(0xbf45b000, 4096, PROT_READ|PROT_WRITE) = 0 mprotect(0xbf45c000, 4096, PROT_READ|PROT_WRITE) = 0 munmap(0xbf45d000, 4096) = 0 mprotect(0xbf45b000, 4096, PROT_NONE) = 0 The 0xbf45c000 allocation seems to be done in response to the malloc(100) call. The page at 0xbf45b000 seems to be some kind of administrative patch. Next comes this: mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf45d000 This is a mmap call made directly by libc, not EF. It's the allocation of the buffer for stdout. Not that it directly follows the already allocated block. Before the code crashes this can be seen: write(1, "line 34\n", 8) = 8 mprotect(0xbf45b000, 4096, PROT_READ|PROT_WRITE) = 0 munmap(0xbf45c000, 8192) = 0 mprotect(0xbf45b000, 4096, PROT_NONE) = 0 The munmap call is made in response to the free() call. Then the program crashes since the buffer for stdout at address 0xbf45d000 has also been freed. Incorrectly so. The problem seems to be that initial munmap() call above. Why did EF create this 4096 byte hole in mapping? It's probably meant to be some kind of protection for the block allocate just below and maybe this should actually be a mprotect() call. Anyway, reassigning to EF.
Created attachment 95507 [details] Output of libSegfault.so attached The failing access is using %ecx
Created attachment 95508 [details] Output of strace Output of strace for the very same run. The end of the strace output shows libSegFault at work. I used strace -o STRACE-OUT -E EF_PROTECT_FREE=1 -E LD_PRELOAD=debug/libSegFault.so ./i
Created attachment 95575 [details] Updated ElectricFence package to fix free bug I updated RawHide version. freddy77
Should be fixed in ElectricFence-2.2.2-19 in rawhide. I actually took a different approach, calling Page_Delete for the guard pages (and in free) always, not just when EF_PROTECT_FREE and changing Page_Delete, so that it does Page_DenyAccess (== mprotect PROT_NONE) and madvise MADV_DONTNEED.