PR/40411: Hisashi T Fujinaka: standalone-tcsh dumps core when tab completing

The new rune code abuses __UNCONST to lazily initialize _RuneLocale. If
that happens to be the _DefaultRuneLocale which is const, the program will
core-dump because it will attempt to write to read-only memory. Catch this
and clone a copy of the locale and return it. The reason we don't see
everything core-dumping is because our shared library code probably loads
the text segment COW so it works (Is there an mprotect missing somewhere?).
But on statically linked binaries this is not the case and we die.

XXX[1]: Vet the code so that we are sure that there is no more of that
        happening trying to get rid of much of the __UNCONST'ing.
XXX[2]: This needs to be fixed for 5.0 and all related fixes.
XXX[3]: There is one place in the code where _DefaultRuneLocale is treated
	specially, does the patch break things?
This commit is contained in:
christos 2009-01-16 21:12:11 +00:00
parent 0da9122630
commit 826ddf7ef5
4 changed files with 20 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: _wctrans.c,v 1.8 2009/01/11 02:46:28 christos Exp $ */
/* $NetBSD: _wctrans.c,v 1.9 2009/01/16 21:12:11 christos Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
@ -60,7 +60,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: _wctrans.c,v 1.8 2009/01/11 02:46:28 christos Exp $");
__RCSID("$NetBSD: _wctrans.c,v 1.9 2009/01/16 21:12:11 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -76,9 +76,14 @@ __RCSID("$NetBSD: _wctrans.c,v 1.8 2009/01/11 02:46:28 christos Exp $");
* _wctrans_init:
*/
void
_RuneLocale *
_wctrans_init(_RuneLocale *rl)
{
if (rl == &_DefaultRuneLocale) {
if ((rl = malloc(sizeof(*rl))) == NULL)
return NULL;
(void)memcpy(rl, &_DefaultRuneLocale, sizeof(*rl))
}
rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name = "tolower";
rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_cached = rl->rl_maplower;
rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_extmap = &rl->rl_maplower_ext;

View File

@ -1,4 +1,4 @@
/* $NetBSD: _wctrans_local.h,v 1.4 2009/01/11 02:46:28 christos Exp $ */
/* $NetBSD: _wctrans_local.h,v 1.5 2009/01/16 21:12:11 christos Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
@ -31,7 +31,7 @@
__BEGIN_DECLS
wint_t _towctrans_ext(wint_t, _WCTransEntry *);
void _wctrans_init(_RuneLocale *);
_RuneLocale *_wctrans_init(_RuneLocale *);
__END_DECLS
static __inline wint_t
@ -44,16 +44,16 @@ _towctrans(wint_t c, _WCTransEntry *te)
static __inline struct _WCTransEntry *
_wctrans_lower(_RuneLocale *rl)
{
if (rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name==NULL)
_wctrans_init(rl);
if (rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name == NULL)
rl = _wctrans_init(rl);
return (&rl->rl_wctrans[_WCTRANS_INDEX_LOWER]);
}
static __inline struct _WCTransEntry *
_wctrans_upper(_RuneLocale *rl)
{
if (rl->rl_wctrans[_WCTRANS_INDEX_UPPER].te_name==NULL)
_wctrans_init(rl);
if (rl->rl_wctrans[_WCTRANS_INDEX_UPPER].te_name == NULL)
rl = _wctrans_init(rl);
return (&rl->rl_wctrans[_WCTRANS_INDEX_UPPER]);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: _wctype.c,v 1.2 2009/01/11 02:46:28 christos Exp $ */
/* $NetBSD: _wctype.c,v 1.3 2009/01/16 21:12:11 christos Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -60,7 +60,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: _wctype.c,v 1.2 2009/01/11 02:46:28 christos Exp $");
__RCSID("$NetBSD: _wctype.c,v 1.3 2009/01/16 21:12:11 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -127,7 +127,7 @@ _towctrans_priv(_RuneLocale const *rl,
if (wc == WEOF)
return wc;
if (te->te_name == NULL)
_wctrans_init(__UNCONST(rl));
rl = _wctrans_init(__UNCONST(rl));
if (_RUNE_ISCACHED(wc))
return te->te_cached[(size_t)wc];
wc0 = (__nbrune_t)wc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: iswctype_mb.c,v 1.2 2009/01/11 02:46:28 christos Exp $ */
/* $NetBSD: iswctype_mb.c,v 1.3 2009/01/16 21:12:11 christos Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: iswctype_mb.c,v 1.2 2009/01/11 02:46:28 christos Exp $");
__RCSID("$NetBSD: iswctype_mb.c,v 1.3 2009/01/16 21:12:11 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -112,7 +112,7 @@ wctrans(const char *charmap)
rl = _RUNE_LOCALE();
if (rl->rl_wctrans[_WCTRANS_INDEX_LOWER].te_name == NULL)
_wctrans_init(__UNCONST(rl));
rl = _wctrans_init(__UNCONST(rl));
for (i = 0; i < _WCTRANS_NINDEXES; ++i) {
if (!strcmp(rl->rl_wctrans[i].te_name, charmap))
return (wctrans_t)__UNCONST(&rl->rl_wctype[i]);