Calling function mblen(3) in EUC locales results in crash and segmentation fault. To repeat the problem, both setlocale(3) and uselocale(3) must be called before calling mblen(3). I think it is because the value of _CurrentRuneLocale->__variable in /usr/src/lib/libc/locale/euc.c is always NULL after calling both setlocale(3) and uselocale(3). Fix: diff -ur /usr/src/lib/libc/locale/euc.c locale/euc.c --- /usr/src/lib/libc/locale/euc.c 2013-09-27 10:07:50.000000000 +0900 +++ locale/euc.c 2014-03-29 06:16:10.000000000 +0900 @@ -134,7 +134,8 @@ return (ps == NULL || ((const _EucState *)ps)->want == 0); } -#define CEI ((_EucInfo *)(_CurrentRuneLocale->__variable)) +#define CEI \ + ((_EucInfo *)(XLOCALE_CTYPE(__get_locale())->runes->__variable)) #define _SS2 0x008e #define _SS3 0x008f Patch attached with submission follows: How-To-Repeat: % cat main.c #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <xlocale.h> int main(void) { printf("setlocale: %s\n", setlocale(LC_ALL, "")); locale_t newLocale = newlocale(LC_ALL_MASK, "C", NULL); locale_t oldLocale = uselocale(newLocale); /* ... */ uselocale(oldLocale); printf("%d\n", mblen("a", 1)); return 0; } % gcc -g3 -std=c99 main.c % setenv LC_MESSAGES C % env LANG=zh_CN.eucCN ./a.out setlocale: zh_CN.eucCN/zh_CN.eucCN/zh_CN.eucCN/zh_CN.eucCN/zh_CN.eucCN/C Segmentation fault (core dumped) % env LANG=ko_KR.eucKR ./a.out setlocale: ko_KR.eucKR/ko_KR.eucKR/ko_KR.eucKR/ko_KR.eucKR/ko_KR.eucKR/C Segmentation fault (core dumped) % env LANG=ja_JP.eucJP ./a.out setlocale: ja_JP.eucJP/ja_JP.eucJP/ja_JP.eucJP/ja_JP.eucJP/ja_JP.eucJP/C Segmentation fault (core dumped) % env LANG=ja_JP.UTF-8 ./a.out setlocale: ja_JP.UTF-8/ja_JP.UTF-8/ja_JP.UTF-8/ja_JP.UTF-8/ja_JP.UTF-8/C 1
I think the fix should actually be: Index: locale/euc.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- locale/euc.c (revision 263226) +++ locale/euc.c (working copy) @@ -134,7 +134,7 @@ return (ps =3D=3D NULL || ((const _EucState *)ps)->want =3D=3D = 0); } =20 -#define CEI ((_EucInfo *)(_CurrentRuneLocale->__variable)) +#define CEI ((_EucInfo = *)(__getCurrentRuneLocale()->__variable)) =20 #define _SS2 0x008e #define _SS3 0x008f Please can you test this and let me know if it fixes it for you? David=
Actually, I'm not sure how this bug can manifest, unless you've somehow = built libc with the wrong headers. In runtype.h (which is included in = euc.c), we have this: #define _CurrentRuneLocale (__getCurrentRuneLocale()) So these two versions should expand to the same thing. =20 David
Author: theraven Date: Wed Apr 2 11:10:46 2014 New Revision: 264038 URL: http://svnweb.freebsd.org/changeset/base/264038 Log: 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 Modified: head/lib/libc/locale/setrunelocale.c head/lib/libc/locale/xlocale.c Modified: head/lib/libc/locale/setrunelocale.c ============================================================================== --- head/lib/libc/locale/setrunelocale.c Wed Apr 2 10:57:11 2014 (r264037) +++ head/lib/libc/locale/setrunelocale.c Wed Apr 2 11:10:46 2014 (r264038) @@ -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; } Modified: head/lib/libc/locale/xlocale.c ============================================================================== --- head/lib/libc/locale/xlocale.c Wed Apr 2 10:57:11 2014 (r264037) +++ head/lib/libc/locale/xlocale.c Wed Apr 2 11:10:46 2014 (r264038) @@ -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); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
In head, needs MFC.
Hi. Can someone MFC this? The patch surely fixes the issue on FreeBSD 9.3-STABLE #0 r279827 i386. Thanks.
Take.
A commit references this bug: Author: delphij Date: Wed Jun 17 19:12:19 UTC 2015 New revision: 284524 URL: https://svnweb.freebsd.org/changeset/base/284524 Log: MFC r264038 (theraven): 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 Changes: _U stable/10/ stable/10/lib/libc/locale/setrunelocale.c stable/10/lib/libc/locale/xlocale.c
A commit references this bug: Author: delphij Date: Wed Jun 17 19:13:14 UTC 2015 New revision: 284525 URL: https://svnweb.freebsd.org/changeset/base/284525 Log: MFC r264038 (theraven) 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 Changes: _U stable/9/lib/libc/ stable/9/lib/libc/locale/setrunelocale.c stable/9/lib/libc/locale/xlocale.c
Note MFC's: 9/ and 10/ were done. 8/ doesn't have xlocale(3) and is therefore not affected.
Resolved as of EN-15:09.