| Summary: | Codeset conversion to Chinese Simplified (HZ) is broken / segfaults | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Manuel <manuel-freebsd> | ||||||||
| Component: | misc | Assignee: | Tijl Coosemans <tijl> | ||||||||
| Status: | Closed FIXED | ||||||||||
| Severity: | Affects Only Me | CC: | xistence | ||||||||
| Priority: | Normal | ||||||||||
| Version: | 10.0-RELEASE | ||||||||||
| Hardware: | Any | ||||||||||
| OS: | Any | ||||||||||
| Attachments: |
|
||||||||||
Attached are patches against head to fix the reported problem + another one I discovered during testing: iconv-void-ptr-ptr.patch ...fixes the reported segfault, however HZ conversion still doesn't work. iconv-HZ-start-comes-before-end.patch ...makes HZ conversion work. Verified using libiconv HZ test file. iconv-VIQR-boundary-check.patch ...fixes a missing boundary check crash in VIQR codeset conversion module I've discovered. cheers, manuel This bug does not seem to affect only explicit conversion to Chinese. At least it breaks the deskutils/fbreader port (it coredumps at startup with the deeper frames identical to those mentionned in the bug report). The patches attached to the first followup fix this as well. Could you consider increasing its priority ? Best regards, Philippe Michel Responsible Changed From-To: freebsd-bugs->tijl Take. Author: tijl Date: Mon Feb 24 13:33:20 2014 New Revision: 262441 URL: http://svnweb.freebsd.org/changeset/base/262441 Log: Consistently pass around context information using a simple pointer. This fixes some dereferencing bugs in Chinese character set conversions. PR: 185964 MFC after: 5 days Modified: head/lib/libc/iconv/citrus_prop.c head/lib/libc/iconv/citrus_prop.h head/lib/libiconv_modules/BIG5/citrus_big5.c head/lib/libiconv_modules/HZ/citrus_hz.c Modified: head/lib/libc/iconv/citrus_prop.c ============================================================================== --- head/lib/libc/iconv/citrus_prop.c Mon Feb 24 12:45:03 2014 (r262440) +++ head/lib/libc/iconv/citrus_prop.c Mon Feb 24 13:33:20 2014 (r262441) @@ -339,7 +339,7 @@ name_found: static int _citrus_prop_parse_element(struct _memstream * __restrict ms, - const _citrus_prop_hint_t * __restrict hints, void ** __restrict context) + const _citrus_prop_hint_t * __restrict hints, void * __restrict context) { int ch, errnum; #define _CITRUS_PROP_HINT_NAME_LEN_MAX 255 @@ -435,8 +435,7 @@ _citrus_prop_parse_variable(const _citru if (ch == EOF || ch == '\0') break; _memstream_ungetc(&ms, ch); - errnum = _citrus_prop_parse_element( - &ms, hints, (void ** __restrict)context); + errnum = _citrus_prop_parse_element(&ms, hints, context); if (errnum != 0) return (errnum); } Modified: head/lib/libc/iconv/citrus_prop.h ============================================================================== --- head/lib/libc/iconv/citrus_prop.h Mon Feb 24 12:45:03 2014 (r262440) +++ head/lib/libc/iconv/citrus_prop.h Mon Feb 24 13:33:20 2014 (r262441) @@ -42,7 +42,7 @@ typedef struct _citrus_prop_hint_t _citr #define _CITRUS_PROP_CB0_T(_func_, _type_) \ typedef int (*_citrus_prop_##_func_##_cb_func_t) \ - (void ** __restrict, const char *, _type_); \ + (void * __restrict, const char *, _type_); \ typedef struct { \ _citrus_prop_##_func_##_cb_func_t func; \ } _citrus_prop_##_func_##_cb_t; @@ -52,7 +52,7 @@ _CITRUS_PROP_CB0_T(str, const char *) #define _CITRUS_PROP_CB1_T(_func_, _type_) \ typedef int (*_citrus_prop_##_func_##_cb_func_t) \ - (void ** __restrict, const char *, _type_, _type_); \ + (void * __restrict, const char *, _type_, _type_); \ typedef struct { \ _citrus_prop_##_func_##_cb_func_t func; \ } _citrus_prop_##_func_##_cb_t; Modified: head/lib/libiconv_modules/BIG5/citrus_big5.c ============================================================================== --- head/lib/libiconv_modules/BIG5/citrus_big5.c Mon Feb 24 12:45:03 2014 (r262440) +++ head/lib/libiconv_modules/BIG5/citrus_big5.c Mon Feb 24 13:33:20 2014 (r262441) @@ -172,7 +172,7 @@ _citrus_BIG5_check_excludes(_BIG5Encodin } static int -_citrus_BIG5_fill_rowcol(void ** __restrict ctx, const char * __restrict s, +_citrus_BIG5_fill_rowcol(void * __restrict ctx, const char * __restrict s, uint64_t start, uint64_t end) { _BIG5EncodingInfo *ei; @@ -191,7 +191,7 @@ _citrus_BIG5_fill_rowcol(void ** __restr static int /*ARGSUSED*/ -_citrus_BIG5_fill_excludes(void ** __restrict ctx, +_citrus_BIG5_fill_excludes(void * __restrict ctx, const char * __restrict s __unused, uint64_t start, uint64_t end) { _BIG5EncodingInfo *ei; @@ -237,7 +237,6 @@ static int _citrus_BIG5_encoding_module_init(_BIG5EncodingInfo * __restrict ei, const void * __restrict var, size_t lenvar) { - void *ctx = (void *)ei; const char *s; int err; @@ -259,9 +258,9 @@ _citrus_BIG5_encoding_module_init(_BIG5E } /* fallback Big5-1984, for backward compatibility. */ - _citrus_BIG5_fill_rowcol((void **)&ctx, "row", 0xA1, 0xFE); - _citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0x40, 0x7E); - _citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0xA1, 0xFE); + _citrus_BIG5_fill_rowcol(ei, "row", 0xA1, 0xFE); + _citrus_BIG5_fill_rowcol(ei, "col", 0x40, 0x7E); + _citrus_BIG5_fill_rowcol(ei, "col", 0xA1, 0xFE); return (0); } Modified: head/lib/libiconv_modules/HZ/citrus_hz.c ============================================================================== --- head/lib/libiconv_modules/HZ/citrus_hz.c Mon Feb 24 12:45:03 2014 (r262440) +++ head/lib/libiconv_modules/HZ/citrus_hz.c Mon Feb 24 13:33:20 2014 (r262441) @@ -505,12 +505,12 @@ _citrus_HZ_encoding_module_uninit(_HZEnc } static int -_citrus_HZ_parse_char(void **context, const char *name __unused, const char *s) +_citrus_HZ_parse_char(void *context, const char *name __unused, const char *s) { escape_t *escape; void **p; - p = (void **)*context; + p = (void **)context; escape = (escape_t *)p[0]; if (escape->ch != '\0') return (EINVAL); @@ -522,14 +522,14 @@ _citrus_HZ_parse_char(void **context, co } static int -_citrus_HZ_parse_graphic(void **context, const char *name, const char *s) +_citrus_HZ_parse_graphic(void *context, const char *name, const char *s) { _HZEncodingInfo *ei; escape_t *escape; graphic_t *graphic; void **p; - p = (void **)*context; + p = (void **)context; escape = (escape_t *)p[0]; ei = (_HZEncodingInfo *)p[1]; graphic = malloc(sizeof(*graphic)); @@ -591,13 +591,13 @@ _CITRUS_PROP_HINT_END }; static int -_citrus_HZ_parse_escape(void **context, const char *name, const char *s) +_citrus_HZ_parse_escape(void *context, const char *name, const char *s) { _HZEncodingInfo *ei; escape_t *escape; void *p[2]; - ei = (_HZEncodingInfo *)*context; + ei = (_HZEncodingInfo *)context; escape = malloc(sizeof(*escape)); if (escape == NULL) return (EINVAL); _______________________________________________ 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" Author: tijl Date: Mon Feb 24 13:43:11 2014 New Revision: 262442 URL: http://svnweb.freebsd.org/changeset/base/262442 Log: Fix Simplified Chinese character set conversions by switching around the fields of an internal struct so it corresponds with the way variables of this type are initialised. PR: 185964 Submitted by: Manuel Mausz <manuel-freebsd@mausz.at> MFC after: 5 days Modified: head/lib/libiconv_modules/HZ/citrus_hz.c Modified: head/lib/libiconv_modules/HZ/citrus_hz.c ============================================================================== --- head/lib/libiconv_modules/HZ/citrus_hz.c Mon Feb 24 13:33:20 2014 (r262441) +++ head/lib/libiconv_modules/HZ/citrus_hz.c Mon Feb 24 13:43:11 2014 (r262442) @@ -65,8 +65,8 @@ typedef enum { } charset_t; typedef struct { - int end; int start; + int end; int width; } range_t; _______________________________________________ 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" Author: tijl Date: Mon Feb 24 14:40:28 2014 New Revision: 262447 URL: http://svnweb.freebsd.org/changeset/base/262447 Log: Fix an array index out of bounds bug in iconv VIQR (Vietnamese) module. PR: 185964 Submitted by: Manuel Mausz <manuel-freebsd@mausz.at> MFC after: 5 days Modified: head/lib/libiconv_modules/VIQR/citrus_viqr.c Modified: head/lib/libiconv_modules/VIQR/citrus_viqr.c ============================================================================== --- head/lib/libiconv_modules/VIQR/citrus_viqr.c Mon Feb 24 13:59:23 2014 (r262446) +++ head/lib/libiconv_modules/VIQR/citrus_viqr.c Mon Feb 24 14:40:28 2014 (r262447) @@ -457,7 +457,7 @@ _citrus_VIQR_encoding_module_init(_VIQRE return (errnum); } } - for (i = 0;; ++i) { + for (i = 0; i < mnemonic_ext_size; ++i) { p = &mnemonic_ext[i]; n = strlen(p->name); if (ei->mb_cur_max < n) _______________________________________________ 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" State Changed From-To: open->patched Committed in r262441, r262442 and r262447. Author: tijl Date: Tue Mar 4 11:43:01 2014 New Revision: 262731 URL: http://svnweb.freebsd.org/changeset/base/262731 Log: MFC r262441-262442,262447,262461-262464,262655: - Consistently pass around context information using a simple pointer. This fixes some dereferencing bugs in Chinese character set conversions. - Fix Simplified Chinese character set conversions by switching around the fields of an internal struct so it corresponds with the way variables of this type are initialised. - Fix an array index out of bounds bug in iconv VIQR (Vietnamese) module. - Silence gcc warning about unsigned comparison with 0. Also record r258316 and r258587 as merged so they no longer show up as eligible. PR: 185964 Submitted by: Manuel Mausz <manuel-freebsd@mausz.at> Modified: stable/10/lib/libc/iconv/citrus_prop.c stable/10/lib/libc/iconv/citrus_prop.h stable/10/lib/libiconv_modules/BIG5/citrus_big5.c stable/10/lib/libiconv_modules/HZ/citrus_hz.c stable/10/lib/libiconv_modules/VIQR/citrus_viqr.c Directory Properties: stable/10/ (props changed) Modified: stable/10/lib/libc/iconv/citrus_prop.c ============================================================================== --- stable/10/lib/libc/iconv/citrus_prop.c Tue Mar 4 10:47:35 2014 (r262730) +++ stable/10/lib/libc/iconv/citrus_prop.c Tue Mar 4 11:43:01 2014 (r262731) @@ -339,7 +339,7 @@ name_found: static int _citrus_prop_parse_element(struct _memstream * __restrict ms, - const _citrus_prop_hint_t * __restrict hints, void ** __restrict context) + const _citrus_prop_hint_t * __restrict hints, void * __restrict context) { int ch, errnum; #define _CITRUS_PROP_HINT_NAME_LEN_MAX 255 @@ -435,8 +435,7 @@ _citrus_prop_parse_variable(const _citru if (ch == EOF || ch == '\0') break; _memstream_ungetc(&ms, ch); - errnum = _citrus_prop_parse_element( - &ms, hints, (void ** __restrict)context); + errnum = _citrus_prop_parse_element(&ms, hints, context); if (errnum != 0) return (errnum); } Modified: stable/10/lib/libc/iconv/citrus_prop.h ============================================================================== --- stable/10/lib/libc/iconv/citrus_prop.h Tue Mar 4 10:47:35 2014 (r262730) +++ stable/10/lib/libc/iconv/citrus_prop.h Tue Mar 4 11:43:01 2014 (r262731) @@ -42,7 +42,7 @@ typedef struct _citrus_prop_hint_t _citr #define _CITRUS_PROP_CB0_T(_func_, _type_) \ typedef int (*_citrus_prop_##_func_##_cb_func_t) \ - (void ** __restrict, const char *, _type_); \ + (void * __restrict, const char *, _type_); \ typedef struct { \ _citrus_prop_##_func_##_cb_func_t func; \ } _citrus_prop_##_func_##_cb_t; @@ -52,7 +52,7 @@ _CITRUS_PROP_CB0_T(str, const char *) #define _CITRUS_PROP_CB1_T(_func_, _type_) \ typedef int (*_citrus_prop_##_func_##_cb_func_t) \ - (void ** __restrict, const char *, _type_, _type_); \ + (void * __restrict, const char *, _type_, _type_); \ typedef struct { \ _citrus_prop_##_func_##_cb_func_t func; \ } _citrus_prop_##_func_##_cb_t; Modified: stable/10/lib/libiconv_modules/BIG5/citrus_big5.c ============================================================================== --- stable/10/lib/libiconv_modules/BIG5/citrus_big5.c Tue Mar 4 10:47:35 2014 (r262730) +++ stable/10/lib/libiconv_modules/BIG5/citrus_big5.c Tue Mar 4 11:43:01 2014 (r262731) @@ -172,7 +172,7 @@ _citrus_BIG5_check_excludes(_BIG5Encodin } static int -_citrus_BIG5_fill_rowcol(void ** __restrict ctx, const char * __restrict s, +_citrus_BIG5_fill_rowcol(void * __restrict ctx, const char * __restrict s, uint64_t start, uint64_t end) { _BIG5EncodingInfo *ei; @@ -191,7 +191,7 @@ _citrus_BIG5_fill_rowcol(void ** __restr static int /*ARGSUSED*/ -_citrus_BIG5_fill_excludes(void ** __restrict ctx, +_citrus_BIG5_fill_excludes(void * __restrict ctx, const char * __restrict s __unused, uint64_t start, uint64_t end) { _BIG5EncodingInfo *ei; @@ -237,7 +237,6 @@ static int _citrus_BIG5_encoding_module_init(_BIG5EncodingInfo * __restrict ei, const void * __restrict var, size_t lenvar) { - void *ctx = (void *)ei; const char *s; int err; @@ -259,9 +258,9 @@ _citrus_BIG5_encoding_module_init(_BIG5E } /* fallback Big5-1984, for backward compatibility. */ - _citrus_BIG5_fill_rowcol((void **)&ctx, "row", 0xA1, 0xFE); - _citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0x40, 0x7E); - _citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0xA1, 0xFE); + _citrus_BIG5_fill_rowcol(ei, "row", 0xA1, 0xFE); + _citrus_BIG5_fill_rowcol(ei, "col", 0x40, 0x7E); + _citrus_BIG5_fill_rowcol(ei, "col", 0xA1, 0xFE); return (0); } Modified: stable/10/lib/libiconv_modules/HZ/citrus_hz.c ============================================================================== --- stable/10/lib/libiconv_modules/HZ/citrus_hz.c Tue Mar 4 10:47:35 2014 (r262730) +++ stable/10/lib/libiconv_modules/HZ/citrus_hz.c Tue Mar 4 11:43:01 2014 (r262731) @@ -65,8 +65,8 @@ typedef enum { } charset_t; typedef struct { - int end; int start; + int end; int width; } range_t; @@ -505,12 +505,12 @@ _citrus_HZ_encoding_module_uninit(_HZEnc } static int -_citrus_HZ_parse_char(void **context, const char *name __unused, const char *s) +_citrus_HZ_parse_char(void *context, const char *name __unused, const char *s) { escape_t *escape; void **p; - p = (void **)*context; + p = (void **)context; escape = (escape_t *)p[0]; if (escape->ch != '\0') return (EINVAL); @@ -522,14 +522,14 @@ _citrus_HZ_parse_char(void **context, co } static int -_citrus_HZ_parse_graphic(void **context, const char *name, const char *s) +_citrus_HZ_parse_graphic(void *context, const char *name, const char *s) { _HZEncodingInfo *ei; escape_t *escape; graphic_t *graphic; void **p; - p = (void **)*context; + p = (void **)context; escape = (escape_t *)p[0]; ei = (_HZEncodingInfo *)p[1]; graphic = malloc(sizeof(*graphic)); @@ -591,13 +591,13 @@ _CITRUS_PROP_HINT_END }; static int -_citrus_HZ_parse_escape(void **context, const char *name, const char *s) +_citrus_HZ_parse_escape(void *context, const char *name, const char *s) { _HZEncodingInfo *ei; escape_t *escape; void *p[2]; - ei = (_HZEncodingInfo *)*context; + ei = (_HZEncodingInfo *)context; escape = malloc(sizeof(*escape)); if (escape == NULL) return (EINVAL); Modified: stable/10/lib/libiconv_modules/VIQR/citrus_viqr.c ============================================================================== --- stable/10/lib/libiconv_modules/VIQR/citrus_viqr.c Tue Mar 4 10:47:35 2014 (r262730) +++ stable/10/lib/libiconv_modules/VIQR/citrus_viqr.c Tue Mar 4 11:43:01 2014 (r262731) @@ -433,7 +433,6 @@ static int _citrus_VIQR_encoding_module_init(_VIQREncodingInfo * __restrict ei, const void * __restrict var __unused, size_t lenvar __unused) { - const mnemonic_def_t *p; const char *s; size_t i, n; int errnum; @@ -457,7 +456,10 @@ _citrus_VIQR_encoding_module_init(_VIQRE return (errnum); } } - for (i = 0;; ++i) { + /* a + 1 < b + 1 here to silence gcc warning about unsigned < 0. */ + for (i = 0; i + 1 < mnemonic_ext_size + 1; ++i) { + const mnemonic_def_t *p; + p = &mnemonic_ext[i]; n = strlen(p->name); if (ei->mb_cur_max < n) _______________________________________________ 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" State Changed From-To: patched->closed Merged to stable/10 in r262731. I understand this has already been resolved and MFC'ed back to 10-STABLE, this however is causing any program compiled against the base system libiconv to segfault. In my case this is a DoS that is causing email to not be delivered in time. For me specifically that means that certain emails to users are causing my Dovecot processes to crash in libiconv. Is there any way to make this an errata that gets a -pX for 10.0-RELEASE? Or is there some way to have all the items in the ports tree built against converters/libiconv instead of against the base system libiconv if USES=iconv is set. (In reply to xistence from comment #10) > I understand this has already been resolved and MFC'ed back to 10-STABLE, > this however is causing any program compiled against the base system > libiconv to segfault. In my case this is a DoS that is causing email to not > be delivered in time. > > For me specifically that means that certain emails to users are causing my > Dovecot processes to crash in libiconv. > > Is there any way to make this an errata that gets a -pX for 10.0-RELEASE? Or > is there some way to have all the items in the ports tree built against > converters/libiconv instead of against the base system libiconv if > USES=iconv is set. As a workaround you can modify the Dovecot port Makefile. Look for a line starting with "USES=" and replace "iconv" with "iconv:translit" there. That should make it compile against converters/libiconv. |
Codeset conversion to Chinese Simplified (HZ) is broken and just segfaults Fix: none known How-To-Repeat: $ echo "foo" | /usr/bin/iconv -f UTF-8 -t HZ ... or ... $ echo "foo" | /usr/bin/iconv -f UTF-8 -t HZ8 ... or ... $ echo "foo" | /usr/bin/iconv -f UTF-8 -t HZ-GB-2312 gdb backtrace: #0 0x0000000801a034af in _citrus_HZ_stdenc_getops () from /usr/lib/i18n/libHZ.so.4 #1 0x0000000800a931a9 in _citrus_prop_parse_variable () from /lib/libc.so.7 #2 0x0000000801a02abf in ?? () from /usr/lib/i18n/libHZ.so.4 #3 0x0000000800a92db9 in _citrus_stdenc_open () from /lib/libc.so.7 #4 0x0000000800dd69ef in ?? () from /usr/lib/i18n/libiconv_std.so.4 #5 0x0000000800a94832 in _citrus_lookup_factory_convert () from /lib/libc.so.7 #6 0x0000000800a926db in __bsd_iconv_open () from /lib/libc.so.7#