summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authortheraven <theraven@FreeBSD.org>2014-04-02 11:10:46 +0000
committertheraven <theraven@FreeBSD.org>2014-04-02 11:10:46 +0000
commite9b954067d7744a304cee94ad75b419594e1c2ce (patch)
treeabc10866a5d9b37cae933eaf2387e6115c5ea89b /lib/libc
parente91051ce20c34a8c697f125b4d4e122bff3fc360 (diff)
downloadFreeBSD-src-e9b954067d7744a304cee94ad75b419594e1c2ce.zip
FreeBSD-src-e9b954067d7744a304cee94ad75b419594e1c2ce.tar.gz
Fix an issue where the locale and rune locale could become out of sync,
causing mb* functions (and similar) to be called with the wrong data (possibly a null pointer, causing a crash). PR: standards/188036 MFC after: 1 week
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/locale/setrunelocale.c2
-rw-r--r--lib/libc/locale/xlocale.c16
2 files changed, 9 insertions, 9 deletions
diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c
index 49e6f6e..0a0943f 100644
--- a/lib/libc/locale/setrunelocale.c
+++ b/lib/libc/locale/setrunelocale.c
@@ -202,6 +202,8 @@ __set_thread_rune_locale(locale_t loc)
if (loc == NULL) {
_ThreadRuneLocale = &_DefaultRuneLocale;
+ } else if (loc == LC_GLOBAL_LOCALE) {
+ _ThreadRuneLocale = 0;
} else {
_ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes;
}
diff --git a/lib/libc/locale/xlocale.c b/lib/libc/locale/xlocale.c
index e114bac..f9b7db1 100644
--- a/lib/libc/locale/xlocale.c
+++ b/lib/libc/locale/xlocale.c
@@ -154,23 +154,24 @@ __get_locale(void)
static void
set_thread_locale(locale_t loc)
{
+ locale_t l = (loc == LC_GLOBAL_LOCALE) ? 0 : loc;
_once(&once_control, init_key);
- if (NULL != loc) {
- xlocale_retain((struct xlocale_refcounted*)loc);
+ if (NULL != l) {
+ xlocale_retain((struct xlocale_refcounted*)l);
}
locale_t old = pthread_getspecific(locale_info_key);
- if ((NULL != old) && (loc != old)) {
+ if ((NULL != old) && (l != old)) {
xlocale_release((struct xlocale_refcounted*)old);
}
if (fake_tls) {
- thread_local_locale = loc;
+ thread_local_locale = l;
} else {
- pthread_setspecific(locale_info_key, loc);
+ pthread_setspecific(locale_info_key, l);
}
#ifndef __NO_TLS
- __thread_locale = loc;
+ __thread_locale = l;
__set_thread_rune_locale(loc);
#endif
}
@@ -361,9 +362,6 @@ locale_t uselocale(locale_t loc)
{
locale_t old = get_thread_locale();
if (NULL != loc) {
- if (LC_GLOBAL_LOCALE == loc) {
- loc = NULL;
- }
set_thread_locale(loc);
}
return (old ? old : LC_GLOBAL_LOCALE);
OpenPOWER on IntegriCloud