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:
parent
0da9122630
commit
826ddf7ef5
@ -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;
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user