Description of problem: Program using widec set_field_buffer crashes with *** glibc detected *** ./a.out: double free or corruption (out): 0x08a76f18 *** Version-Release number of selected component (if applicable): ncurses-5.6-6.20070303.fc7 How reproducible: See attached source file. Compile with: gcc main.c -lncursesw -lformw -lpanelw -I/usr/include/ -I/usr/include/ncursesw/ Steps to Reproduce: 1. compile 2. run ./a.out Actual results: *** glibc detected *** ./a.out: double free or corruption (out): 0x08e7bf18 *** ======= Backtrace: ========= /lib/libc.so.6[0xaefdf1] /lib/libc.so.6(cfree+0x90)[0xaf3430] /usr/lib/libformw.so.5(set_field_buffer+0x251)[0x1407e1] ./a.out[0x8048e64] /lib/libc.so.6(__libc_start_main+0xe0)[0xa9df70] ./a.out[0x8048b11] ======= Memory map: ======== 00110000-00111000 r-xp 00110000 00:00 0 [vdso] 00111000-00138000 r-xp 00000000 fd:00 1449608 /usr/lib/libncursesw.so.5.6 00138000-00139000 rwxp 00027000 fd:00 1449608 /usr/lib/libncursesw.so.5.6 00139000-00147000 r-xp 00000000 fd:00 1446265 /usr/lib/libformw.so.5.6 00147000-00148000 rwxp 0000d000 fd:00 1446265 /usr/lib/libformw.so.5.6 00148000-0014b000 r-xp 00000000 fd:00 1458024 /usr/lib/libpanelw.so.5.6 0014b000-0014c000 rwxp 00002000 fd:00 1458024 /usr/lib/libpanelw.so.5.6 0014c000-00161000 r-xp 00000000 fd:00 3270610 /lib/libtinfo.so.5.6 00161000-00164000 rwxp 00014000 fd:00 3270610 /lib/libtinfo.so.5.6 00a69000-00a84000 r-xp 00000000 fd:00 3270649 /lib/ld-2.6.so 00a84000-00a85000 r-xp 0001a000 fd:00 3270649 /lib/ld-2.6.so 00a85000-00a86000 rwxp 0001b000 fd:00 3270649 /lib/ld-2.6.so 00a88000-00bd6000 r-xp 00000000 fd:00 3270652 /lib/libc-2.6.so 00bd6000-00bd8000 r-xp 0014e000 fd:00 3270652 /lib/libc-2.6.so 00bd8000-00bd9000 rwxp 00150000 fd:00 3270652 /lib/libc-2.6.so 00bd9000-00bdc000 rwxp 00bd9000 00:00 0 00c09000-00c0c000 r-xp 00000000 fd:00 3270659 /lib/libdl-2.6.so 00c0c000-00c0d000 r-xp 00002000 fd:00 3270659 /lib/libdl-2.6.so 00c0d000-00c0e000 rwxp 00003000 fd:00 3270659 /lib/libdl-2.6.so 053a3000-053ae000 r-xp 00000000 fd:00 3270693 /lib/libgcc_s-4.1.2-20070503.so.1 053ae000-053af000 rwxp 0000a000 fd:00 3270693 /lib/libgcc_s-4.1.2-20070503.so.1 08048000-0804a000 r-xp 00000000 fd:00 327349 /tmp/a.out 0804a000-0804b000 rw-p 00001000 fd:00 327349 /tmp/a.out 08e4f000-08e91000 rw-p 08e4f000 00:00 0 b7e00000-b7e21000 rw-p b7e00000 00:00 0 b7e21000-b7f00000 ---p b7e21000 00:00 0 b7ff0000-b7ff3000 rw-p b7ff0000 00:00 0 bfe89000-bfe9f000 rw-p bfe89000 00:00 0 [stack] Aborted (core dumped) Expected results: No error. Additional info: Upstream maintainer can't reproduce this with the latest code. (gdb) bt #0 0x00110402 in __kernel_vsyscall () #1 0x00ab0fa0 in raise () from /lib/libc.so.6 #2 0x00ab28b1 in abort () from /lib/libc.so.6 #3 0x00ae7d6b in __libc_message () from /lib/libc.so.6 #4 0x00aefdf1 in _int_free () from /lib/libc.so.6 #5 0x00af3430 in free () from /lib/libc.so.6 #6 0x001407e1 in set_field_buffer () from /usr/lib/libformw.so.5 #7 0x08048e64 in main ()
Created attachment 209101 [details] Source to reproduce error.
Created attachment 209111 [details] valgrind log
This chunk seems to be relevant (but the previous time that line changed was in 2004/05/30, which was before ncurses 5.5): 20070317 + corrected length of temporary buffer in wide-character version of set_field_buffer() (related to report by Bryan Christ). --- frm_driver.c 2007/02/04 00:28:38 1.78 +++ frm_driver.c 2007/03/12 21:49:00 1.79 @@ -32,7 +32,7 @@ #include "form.priv.h" -MODULE_ID("$Id: frm_driver.c,v 1.77 2007/02/03 23:37:46 tom Exp $") +MODULE_ID("$Id: frm_driver.c,v 1.78 2007/02/04 00:28:38 tom Exp $") /*---------------------------------------------------------------------------- This is the core module of the form library. It contains the majority @@ -4274,7 +4274,7 @@ wclear(field->working); mvwaddstr(field->working, 0, 0, value); - if ((widevalue = (FIELD_CELL *)calloc(len, sizeof(FIELD_CELL))) == 0) + if ((widevalue = (FIELD_CELL *)calloc(len + 1, sizeof(FIELD_CELL))) == 0) { RETURN(E_SYSTEM_ERROR); }
I can confirm that the fix from Thomas E. Dickey solves the problem.
I've updated the package to upstream patch 20070812 which includes the patch. ncurses-5.6-7.20070812.fc7 should land in updates testing repository soon.
ncurses-5.6-7.20070812.fc7 has been pushed to the Fedora 7 testing repository. If problems still persist, please make note of it in this bug report. If you want to test the update, you can install it with su -c 'yum --enablerepo=updates-testing update ncurses'
Thanks for your efforts so far! The set_field_buffer issue seems to be solved with ncurses-5.6-7.20070812.fc7, but I did see another and possibly related issue with field_buffer. I'll try to investigate and create example code tomorrow. Here is valgrind output: ==2781== Invalid write of size 1 ==2781== at 0x403F799: winnstr (in /usr/lib/libncursesw.so.5.6) ==2781== by 0x401C093: field_buffer (in /usr/lib/libformw.so.5.6) ==2781== by 0x80649F4: rulebar_setcolor (in /usr/bin/vuurmuur_conf) ==2781== by 0x806EBD9: rules_form (in /usr/bin/vuurmuur_conf) ==2781== by 0x809F391: main_menu (in /usr/bin/vuurmuur_conf) ==2781== by 0x804E71B: main (in /usr/bin/vuurmuur_conf) ==2781== Address 0x47DA595 is 0 bytes after a block of size 5 alloc'd ==2781== at 0x40054E5: malloc (vg_replace_malloc.c:149) ==2781== by 0x401BFF1: field_buffer (in /usr/lib/libformw.so.5.6) ==2781== by 0x80649F4: rulebar_setcolor (in /usr/bin/vuurmuur_conf) ==2781== by 0x806EBD9: rules_form (in /usr/bin/vuurmuur_conf) ==2781== by 0x809F391: main_menu (in /usr/bin/vuurmuur_conf) ==2781== by 0x804E71B: main (in /usr/bin/vuurmuur_conf) Where can I pick up a src.rpm to be able to enable debug symbols?
Here are all rpms for the package: http://koji.fedoraproject.org/koji/buildinfo?buildID=20177
Created attachment 221091 [details] Code to demonstrate field_buffer issue
Created attachment 221101 [details] Valgrind output for field_buffer issue
This patch seems to fix it. Thomas, is it correct? --- ncurses-5.6/form/frm_driver.c.fieldbuf +++ ncurses-5.6/form/frm_driver.c @@ -4476,7 +4476,7 @@ field_buffer(const FIELD *field, int buf { wclear(field->working); mvwadd_wchnstr(field->working, 0, 0, data, size); - mvwinnstr(field->working, 0, 0, result, (int)need + 1); + mvwinnstr(field->working, 0, 0, result, (int)need); } #else result = Address_Of_Nth_Buffer(field, buffer);
That seems to be correct - the extra count is the trailing null which is always added to the buffer.
Thanks. I'll prepare an updated package.
ncurses-5.6-8.20070812.fc7 has been pushed to the Fedora 7 testing repository. If problems still persist, please make note of it in this bug report. If you want to test the update, you can install it with su -c 'yum --enablerepo=updates-testing update ncurses'
This update fixes the field_buffer issue as well. I can now run my application in valgrind without a single error. Thanks a lot for your efforts Miroslav and Thomas!
I ran into a new and I suspect again related issue. When using fields, extra buffers can be used (nbuffers). When using one extra buffer things work fine, but with two I'm getting errors again. I will attach two sources to show the problem. This problem occurs on Ubuntu's ncurses 5.5 as well btw. Valgrind output: ==3893== 1 errors in context 1 of 4: ==3893== Invalid read of size 4 ==3893== at 0x4044FFD: field_buffer (frm_driver.c:4475) ==3893== by 0x8049004: main (main2.c:114) ==3893== Address 0x413F268 is 0 bytes after a block of size 8 alloc'd ==3893== at 0x4004824: calloc (vg_replace_malloc.c:279) ==3893== by 0x4042D49: new_field (fld_def.c:308) ==3893== by 0x8048DCF: main (main2.c:50) ==3893== ==3893== 1 errors in context 2 of 4: ==3893== Invalid write of size 4 ==3893== at 0x4044FF5: field_buffer (frm_driver.c:4472) ==3893== by 0x8049004: main (main2.c:114) ==3893== Address 0x413F268 is 0 bytes after a block of size 8 alloc'd ==3893== at 0x4004824: calloc (vg_replace_malloc.c:279) ==3893== by 0x4042D49: new_field (fld_def.c:308) ==3893== by 0x8048DCF: main (main2.c:50) ==3893== ==3893== 1 errors in context 3 of 4: ==3893== Invalid read of size 4 ==3893== at 0x4044FD5: field_buffer (frm_driver.c:4470) ==3893== by 0x8049004: main (main2.c:114) ==3893== Address 0x413F268 is 0 bytes after a block of size 8 alloc'd ==3893== at 0x4004824: calloc (vg_replace_malloc.c:279) ==3893== by 0x4042D49: new_field (fld_def.c:308) ==3893== by 0x8048DCF: main (main2.c:50) ==3893== ==3893== 2 errors in context 4 of 4: ==3893== Invalid read of size 4 ==3893== at 0x40429B0: free_field (fld_def.c:389) ==3893== by 0x804904D: main (main2.c:122) ==3893== Address 0x413F268 is 0 bytes after a block of size 8 alloc'd ==3893== at 0x4004824: calloc (vg_replace_malloc.c:279) ==3893== by 0x4042D49: new_field (fld_def.c:308) ==3893== by 0x8048DCF: main (main2.c:50)
Created attachment 225361 [details] this one uses one buffer and works
Created attachment 225371 [details] this one uses two buffers and fails (in valgrind)
Created attachment 225441 [details] Patch to allocate nbuf + 1 working buffers in new_field() Looks like another oneliner. I guess I'll wait with updating for few days to see if more show up ;-).
I suppose so (these are 2-3 year old changes).
Sadly that means that even when they are fixed upstream and in Fedora the functionality is really not usable since distro's like Debian seem to refuse to fix this type of bug (not security related) in their stable releases... :( Thomas is the suggested fix correct? If so I'll try bugging Debian and Ubuntu with it as well... hopefully they will prove me wrong :) Thanks a lot!
Miroslav, your fix seems to work. I'm still developing the code using it, so you may want to wait a little longer to see if more pops up... Thanks again!
It looks okay - seems that was untouched since early 2005 (implemented in mid-2004).
ncurses-5.6-9.20070812.fc7 has been pushed to the Fedora 7 testing repository. If problems still persist, please make note of it in this bug report. If you want to test the update, you can install it with su -c 'yum --enablerepo=updates-testing update ncurses'
I tested it and it works fine. Thanks a lot!
ncurses-5.6-9.20070812.fc7 has been pushed to the Fedora 7 stable repository. If problems still persist, please make note of it in this bug report.