Re: Bug#177793: trn4: SEGVs on startup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi folks,

Here's another report from the Debian bug tracking system, with some
analysis and a patch by me.

On Sun, Feb 02, 2003 at 06:43:06PM +0000, Colin Watson wrote:
> On Tue, Jan 21, 2003 at 10:25:24PM +0000, John Sullivan wrote:
> > Package: trn4
> > Version: 4.0-test76-3
> > 
> > $ uname -a
> > Linux hostname 2.4.18-586tsc #1 Sun Apr 14 10:57:57 EST 2002 i586 unknown
> > $ dpkg -s libc6 | grep ^Version
> > >Version: 2.2.5-11.2
> > $ trn4 +hdate +hfrom +hto +hdate
> > Segmentation fault
> > 
> > Removing any one of the four options makes it work.
> > 
> > (I saw this originally when moving from trn3 - the above options were in
> > ~/.trninit specified by the TRNINIT environment variable. Commenting out
> > the second +hdate fixed it there, though uncommenting it did not bring the
> > crash back. So it may not be reliably reproduceable.)
> 
> Thanks for the report. I can reproduce this here with debugging symbols:
> 
> (gdb) run +hdate +hfrom +hto +hdate
> Starting program: /home/cjwatson/src/debian/trn4/trn4-4.0-test76/trn +hdate +hfrom +hto +hdate
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x08067a11 in set_header (s=0x80cbe34 "", flag=1, setit=0) at opt.c:1133
> 1133                user_htypeix[*user_htype[i].name - 'a'] = i;
> (gdb) bt
> #0  0x08067a11 in set_header (s=0x80cbe34 "", flag=1, setit=0) at opt.c:1133
> #1  0x0807f168 in decode_switch (s=0xbffffb17 "hdate") at sw.c:239
> #2  0x08065a9b in opt_init (argc=5, argv=0xbffff9b4, tcbufptr=0xbffff92c) at opt.c:116
> #3  0x0805850e in initialize (argc=5, argv=0xbffff9b4) at init.c:100
> #4  0x0808378a in main (argc=5, argv=0xbffff9b4) at trn.c:123
> (gdb)
> (gdb) p i
> $1 = 4
> (gdb) p user_htype[i]
> $2 = {name = 0xffffffff <Address 0xffffffff out of bounds>, length = 0 '\0', flags = 0 '\0'}

In set_header(), entries above user_htype_cnt in the user_htype array
are undefined and must not be used. However, line 1124 (in my copy at
least) does not check for this:

           while (user_htype[killed].name != NULL) killed++;

When you use '+hdate +hfrom +hto +hdate', user_htype contains the
following names in order by the time you get to the second +hdate: "*",
"date", "from", "to". set_header() frees user_htype[1] because it knows
it's about to replace it, and sets killed to 1. Then, after it's
reinserted "date", because killed is set, it runs up through the
subsequent items in user_htype to see if it needs to shrink
user_htype_cnt. Unfortunately, user_htype[4].name is undefined, and
happens to be -1, so now it sets user_htype_cnt to 5 instead of 4 and
proceeds to segfault a few lines later.

The fix is to make sure that that while loop doesn't go past
user_htype_cnt, as implemented by the following patch:

--- trn4-4.0-test76.orig/opt.c
+++ trn4-4.0-test76/opt.c
@@ -1121,7 +1121,8 @@
 	    }
 	}
 	if (killed) {
-	    while (user_htype[killed].name != NULL) killed++;
+	    while (killed < user_htype_cnt && user_htype[killed].name != NULL)
+		killed++;
 	    for (i = killed+1; i < user_htype_cnt; i++) {
 		if (user_htype[i].name != NULL)
 		    user_htype[killed++] = user_htype[i];

If no-one objects I'll apply this to CVS.

Cheers,

-- 
Colin Watson                                  [cjwatson@flatline.org.uk]


-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com

[Index of Archives]     [Photo]     [Yosemite]     [Epson Inkjet]     [Mhonarc]     [Nntpcache]

  Powered by Linux