[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: