Subject: Re: lib/30552: small bug in libedit might cause abnormal program
To: Christos Zoulas <christos@zoulas.com>
From: =?ISO-8859-1?Q?Bj=F6rn_K=F6nig?= <bkoenig@cs.tu-berlin.de>
List: netbsd-bugs
Date: 06/21/2005 13:35:45
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--