NetBSD Problem Report #30552
From www@netbsd.org Sat Jun 18 22:04:05 2005
Return-Path: <www@netbsd.org>
Received: by narn.netbsd.org (Postfix, from userid 31301)
id B591063B116; Sat, 18 Jun 2005 22:04:05 +0000 (UTC)
Message-Id: <20050618220405.B591063B116@narn.netbsd.org>
Date: Sat, 18 Jun 2005 22:04:05 +0000 (UTC)
From: bkoenig@cs.tu-berlin.de
Reply-To: bkoenig@cs.tu-berlin.de
To: gnats-bugs@netbsd.org
Subject: small bug in libedit might cause abnormal program termination
X-Send-Pr-Version: www-1.0
>Number: 30552
>Category: lib
>Synopsis: small bug in libedit might cause abnormal program termination
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Jun 18 22:05:00 +0000 2005
>Last-Modified: Tue Jun 21 12:16:01 +0000 2005
>Originator: Björn König
>Release:
>Organization:
>Environment:
>Description:
libedit covers several vi and emacs functions and stores
descriptions about them in a structure called el_func_help
which will be generated automatically. This structure is
terminated by { NULL, 0, NULL } as customary to have an
exit condition for use with loops. The problem is that
the map_init function in lib/libedit/map.c do not respect
this null-termination. It allocates memory for only N
functions, but N+1 is necessary to include the termination.
You'll get a segmentation fault in certain cases.
>How-To-Repeat:
I'm not sure if this works with NetBSD, at least it does with FreeBSD. Unfornately I have no NetBSD system available.
Set a language explicitly if you don't have set any.
> setenv LANG en_US.ISO8859-1
Run a shell with built-in emacs command line editor.
> sh -E
List all editor commands.
$ bind -l 2>/dev/null
Segmentation fault (core dumped)
>Fix:
See http://www.freebsd.org/cgi/query-pr.cgi?pr=82381
>Audit-Trail:
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@netbsd.org, lib-bug-people@netbsd.org,
gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc: bkoenig@cs.tu-berlin.de
Subject: Re: lib/30552: small bug in libedit might cause abnormal program termination
Date: Mon, 20 Jun 2005 20:46:03 -0400
On Jun 18, 10:05pm, bkoenig@cs.tu-berlin.de (bkoenig@cs.tu-berlin.de) wrote:
-- Subject: lib/30552: small bug in libedit might cause abnormal program term
| >Number: 30552
| >Category: lib
| >Synopsis: small bug in libedit might cause abnormal program termination
| >Confidential: no
| >Severity: non-critical
| >Priority: low
| >Responsible: lib-bug-people
| >State: open
| >Class: sw-bug
| >Submitter-Id: net
| >Arrival-Date: Sat Jun 18 22:05:00 +0000 2005
| >Originator: Björn König
| >Release:
| >Organization:
| >Environment:
| >Description:
| libedit covers several vi and emacs functions and stores
| descriptions about them in a structure called el_func_help
| which will be generated automatically. This structure is
| terminated by { NULL, 0, NULL } as customary to have an
| exit condition for use with loops. The problem is that
| the map_init function in lib/libedit/map.c do not respect
| this null-termination. It allocates memory for only N
| functions, but N+1 is necessary to include the termination.
| You'll get a segmentation fault in certain cases.
|
| >How-To-Repeat:
| I'm not sure if this works with NetBSD, at least it does with FreeBSD. Unfornately I have no NetBSD system available.
|
| Set a language explicitly if you don't have set any.
|
| > setenv LANG en_US.ISO8859-1
|
| Run a shell with built-in emacs command line editor.
|
| > sh -E
|
| List all editor commands.
|
| $ bind -l 2>/dev/null
| Segmentation fault (core dumped)
I don't think that is the case. EL_NUM_FCNS is one greater than
the total number of functions. The following does not core-dump...
christos
Index: map.c
===================================================================
RCS file: /cvsroot/src/lib/libedit/map.c,v
retrieving revision 1.20
diff -u -u -r1.20 map.c
--- map.c 13 Aug 2004 12:10:39 -0000 1.20
+++ map.c 21 Jun 2005 00:43:36 -0000
@@ -916,10 +916,18 @@
el->el_map.vii = el_map_vi_insert;
el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
EL_NUM_FCNS);
if (el->el_map.help == NULL)
return (-1);
+ (void) memset(el->el_map.help, 1, sizeof(el_bindings_t) * EL_NUM_FCNS);
(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)
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--
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:42:40 +0200
This is a multi-part message in MIME format.
--------------060209080002060908040400
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
I'm sorry. Try this one instead of my previously sent patch.
Björn
--------------060209080002060908040400
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:39:24 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 sizeof(el_bindings_t) more bytes 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)
--------------060209080002060908040400--
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.