Bug#406946: iconv() crashes during ASCII -> WCHAR_T conversion on sparc
Jurij Smakov a écrit :
> Package: libc6
> Version: 2.3.6.ds1-10
> Severity: important
>
> Hi,
>
> The iconv() function may die with bus error due to unaligned memory
> accesses on sparc and, probably, other platforms with strict alignment
> requirements. It can be occasionally triggered by attempting 'aptitude
> install non-existent-package' (thanks to Al Viro and Fabio M. Di Nitto
> for the report and initial investigation). It also affects etch
> version (2.3.6.ds1-8) as well. The test case (attached) illustrates
> the problem:
>
> jurij@debian:~$ gcc -g iconv-crash.c
> jurij@debian:~$ ./iconv-crash
> Bus error
> jurij@debian:~$ gdb ./iconv-crash
> GNU gdb 6.5-debian
> Copyright (C) 2006 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and you are
> welcome to change it and/or distribute copies of it under certain conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB. Type "show warranty" for details.
> This GDB was configured as "sparc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
>
> (gdb) run
> Starting program: /home/jurij/iconv-crash
>
> Program received signal SIGBUS, Bus error.
> 0xf7e7a1f4 in __gconv_transform_internal_ascii () from /lib/libc.so.6
> (gdb) bt
> #0 0xf7e7a1f4 in __gconv_transform_internal_ascii () from
> /lib/libc.so.6
> #1 0xf7e75df4 in __gconv () from /lib/libc.so.6
> #2 0xf7e752a8 in iconv () from /lib/libc.so.6
> #3 0x000105e0 in main () at iconv-crash.c:15
> (gdb)
>
> AFAICT, the body of the __gconv_transform_internal_ascii() is defined
> in iconv/gconv_simple.c as
>
> #define BODY \
> { \
> if (__builtin_expect (*((const uint32_t *) inptr) > 0x7f, 0)) \
> { \
> UNICODE_TAG_HANDLER (*((const uint32_t *) inptr), 4); \
> STANDARD_TO_LOOP_ERR_HANDLER (4); \
> } \
> else \
> /* It's an one byte sequence. */ \
> *outptr++ = *((const uint32_t *) inptr); \
> inptr += sizeof (uint32_t); \
> }
>
> The word-sized accesses at the potentially unaligned location
> pointed to by inptr are likely to be causing the problem.
>
> Best regards,
>
>
> ------------------------------------------------------------------------
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <iconv.h>
> #include <string.h>
>
> int main()
> {
> iconv_t cd;
> size_t inr = 4, outr = 8, res;
> char *inbuf = strdup("abcde");
> char *outbuf = malloc(8);
>
> inbuf++;
> cd = iconv_open("ASCII", "WCHAR_T");
> res = iconv(cd, &inbuf, &inr, &outbuf, &outr);
>
> return 0;
> }
wchar_t type has a 32-bit size. It is perfectly normal to require a
32-bit alignement on 32-bit types, just like it is already the case on
float and double.
This testcase is buggy, not the iconv code.
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' aurel32@debian.org | aurelien@aurel32.net
`- people.debian.org/~aurel32 | www.aurel32.net
Reply to: