Bug 310071

Summary: Widec set_field_buffer fails with 'double free or corruption' error
Product: [Fedora] Fedora Reporter: Victor Julien <victor>
Component: ncursesAssignee: Miroslav Lichvar <mlichvar>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 7CC: dickey
Target Milestone: ---   
Target Release: ---   
Hardware: i686   
OS: Linux   
Whiteboard:
Fixed In Version: 5.6-9.20070812.fc7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-11-05 15:06:45 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Source to reproduce error.
none
valgrind log
none
Code to demonstrate field_buffer issue
none
Valgrind output for field_buffer issue
none
this one uses one buffer and works
none
this one uses two buffers and fails (in valgrind)
none
Patch to allocate nbuf + 1 working buffers in new_field() none

Description Victor Julien 2007-09-27 22:15:14 UTC
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 ()

Comment 1 Victor Julien 2007-09-27 22:15:14 UTC
Created attachment 209101 [details]
Source to reproduce error.

Comment 2 Victor Julien 2007-09-27 22:16:37 UTC
Created attachment 209111 [details]
valgrind log

Comment 3 Thomas E. Dickey 2007-09-29 16:57:08 UTC
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);                                                  
     }                                                                          


Comment 4 Victor Julien 2007-09-30 14:08:39 UTC
I can confirm that the fix from Thomas E. Dickey solves the problem.

Comment 5 Miroslav Lichvar 2007-10-04 16:06:33 UTC
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.

Comment 6 Fedora Update System 2007-10-08 14:57:04 UTC
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'

Comment 7 Victor Julien 2007-10-08 20:40:29 UTC
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?



Comment 8 Miroslav Lichvar 2007-10-09 07:43:04 UTC
Here are all rpms for the package:
http://koji.fedoraproject.org/koji/buildinfo?buildID=20177

Comment 9 Victor Julien 2007-10-09 10:16:43 UTC
Created attachment 221091 [details]
Code to demonstrate field_buffer issue

Comment 10 Victor Julien 2007-10-09 10:17:37 UTC
Created attachment 221101 [details]
Valgrind output for field_buffer issue

Comment 11 Miroslav Lichvar 2007-10-09 11:31:46 UTC
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);


Comment 12 Thomas E. Dickey 2007-10-09 22:47:22 UTC
That seems to be correct - the extra count is the trailing null which
is always added to the buffer.

Comment 13 Miroslav Lichvar 2007-10-10 08:44:34 UTC
Thanks. I'll prepare an updated package.

Comment 14 Fedora Update System 2007-10-11 01:47:31 UTC
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'

Comment 15 Victor Julien 2007-10-11 07:39:22 UTC
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!

Comment 16 Victor Julien 2007-10-12 11:20:09 UTC
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)

Comment 17 Victor Julien 2007-10-12 11:21:18 UTC
Created attachment 225361 [details]
this one uses one buffer and works

Comment 18 Victor Julien 2007-10-12 11:21:45 UTC
Created attachment 225371 [details]
this one uses two buffers and fails (in valgrind)

Comment 19 Miroslav Lichvar 2007-10-12 12:40:33 UTC
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 ;-).

Comment 20 Thomas E. Dickey 2007-10-12 13:05:30 UTC
I suppose so (these are 2-3 year old changes).

Comment 21 Victor Julien 2007-10-12 13:16:59 UTC
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!


Comment 22 Victor Julien 2007-10-13 12:02:16 UTC
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!


Comment 23 Thomas E. Dickey 2007-10-13 19:38:03 UTC
It looks okay - seems that was untouched since early 2005 (implemented
in mid-2004).

Comment 24 Fedora Update System 2007-10-18 02:28:14 UTC
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'

Comment 25 Victor Julien 2007-10-29 10:54:44 UTC
I tested it and it works fine. Thanks a lot!

Comment 26 Fedora Update System 2007-11-05 15:06:44 UTC
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.