Subject: Re: lib/30552: small bug in libedit might cause abnormal program
To: None <lib-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: =?ISO-8859-1?Q?Bj=F6rn_K=F6nig?= <bkoenig@cs.tu-berlin.de>
List: netbsd-bugs
Date: 06/21/2005 11:59:02
The following reply was made to PR lib/30552; it has been noted by GNATS.

From: =?ISO-8859-1?Q?Bj=F6rn_K=F6nig?= <bkoenig@cs.tu-berlin.de>
To: Christos Zoulas <christos@zoulas.com>
Cc: gnats-bugs@netbsd.org, lib-bug-people@netbsd.org,
	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: lib/30552: small bug in libedit might cause abnormal program
 termination
Date: Tue, 21 Jun 2005 13:35:45 +0200

 This is a multi-part message in MIME format.
 --------------080509050807030204080605
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 8bit
 
 Christos Zoulas wrote:
 
 > I don't think that is the case. EL_NUM_FCNS is one greater than
 > the total number of functions.
 
 It isn't. There are 101 functions in my copy of the repository (numbered 
 from 0 to 100) and EL_NUM_FCNS got the value 101. These steps will be 
 done by the Makefile to generate the header file:
 
    $ cd src/lib/libedit
    $ sh makelist -h vi.c > vi.h
    $ sh makelist -h emacs.c > emacs.h
    $ sh makelist -h common.c > common.h	
    $ sh makelist -fh vi.h emacs.h common.h > fcns.h
    $ tail fcns.h
    #define VI_TO_PREV_CHAR                  95
    #define VI_UNDO                          96
    #define VI_UNDO_LINE                     97
    #define VI_YANK                          98
    #define VI_YANK_END                      99
    #define VI_ZERO                         100
    #define EL_NUM_FCNS                     101
    typedef el_action_t (*el_func_t)(EditLine *, int);
    protected const el_func_t* func__get(void);
    #endif /* _h_fcns_c */
 
 The structure that is returned by help__get() consists of 102 
 el_bindings_t structures including the null-termination:
 
    $ cd src/lib/libedit
    $ sh makelist -bc vi.c emacs.c common.c > help.c
    $ grep -c "^[[:blank:]]*{" help.c
    102
 
 > The following does not core-dump...
 
 ... because you set (101 * sizeof(el_bindings_t)) bytes to "1", then you 
 overwrite (101 * sizeof(el_bindings_t)) bytes with the appropriate 
 structures, but the memory behind is still coincidentally zero.
 
 I modified your small sanity check. Try it now.
 
 Björn
 
 --------------080509050807030204080605
 Content-Type: text/x-patch;
  name="map.c.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="map.c.diff"
 
 --- map.c.orig	Thu Aug  7 18:44:32 2003
 +++ map.c	Tue Jun 21 13:05:15 2005
 @@ -915,11 +915,20 @@
  	el->el_map.vic = el_map_vi_command;
  	el->el_map.vii = el_map_vi_insert;
  	el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
 -	    EL_NUM_FCNS);
 +	    EL_NUM_FCNS + 1);
  	if (el->el_map.help == NULL)
  		return (-1);
 +	/* set one more byte to "1" ... */
 +	(void) memset(el->el_map.help, 1, sizeof(el_bindings_t) * EL_NUM_FCNS + 1);
 +	/* ... but copy only n = EL_NUM_FCNS structures */
  	(void) memcpy(el->el_map.help, help__get(),
  	    sizeof(el_bindings_t) * EL_NUM_FCNS);
 +	{
 +		el_bindings_t *p = el->el_map.help;
 +		for (;p->name;p++)
 +			printf("%s\n", p->name);
 +		printf("done\n");
 +	}
  	el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) *
  	    EL_NUM_FCNS);
  	if (el->el_map.func == NULL)
 
 --------------080509050807030204080605--