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

Bug#234691: Additional information - exact location of SIGBUS



Hi,

After preprocessing the glibc iconv code and running it through the
debugger, I was able to determine the exact place were the SIGBUS occurs:

Program received signal SIGBUS, Bus error.
__gconv_transform_internal_ucs2 (step=0x13385c, data=0x14aca4,
    inptrp=0xefff8a64, inend=0x2dcc18 "", outbufstart=0x0,
    irreversible=0xefff8b64, do_flush=0, consume_incomplete=0)
    at gconv_simple.c:8217
8217                     *((uint16_t *) outptr)++ = val;

Note that the line number is from my preprocessed code. Even though it
says, that the function in which it occurs is __gconv_transform_internal_ucs2
it is really in the function internal_ucs2_loop_unaligned, which is
declared as inline and called from the former. The body of this function
comes from the code snippet in pristine iconv/gconv_simple.c, around line
1164, which is attached to this message. There it may be seen, that val is
declared as uint32_t, so the assignment above might indeed be a problem
due to the size mismatch. So far I was not able to check whether outptr
has a valid value before the offending line, since gdb won't display its
value ("no such symbol in current context"), presumably due to inlining.

Hope it helps,

Jurij Smakov                                        jurij@wooyd.org
Key: http://www.wooyd.org/pgpkey/                   KeyID: C99E03CC
/* Convert from the internal (UCS4-like) format to UCS2.  */
#define DEFINE_INIT		0
#define DEFINE_FINI		0
#define MIN_NEEDED_FROM		4
#define MIN_NEEDED_TO		2
#define FROM_DIRECTION		1
#define FROM_LOOP		internal_ucs2_loop
#define TO_LOOP			internal_ucs2_loop /* This is not used.  */
#define FUNCTION_NAME		__gconv_transform_internal_ucs2
#define ONE_DIRECTION		1

#define MIN_NEEDED_INPUT	MIN_NEEDED_FROM
#define MIN_NEEDED_OUTPUT	MIN_NEEDED_TO
#define LOOPFCT			FROM_LOOP
#define BODY \
  {									      \
    uint32_t val = *((const uint32_t *) inptr);				      \
									      \
    if (__builtin_expect (val >= 0x10000, 0))				      \
      {									      \
	UNICODE_TAG_HANDLER (val, 4);					      \
	STANDARD_TO_LOOP_ERR_HANDLER (4);				      \
      }									      \
    else if (__builtin_expect (val >= 0xd800 && val < 0xe000, 0))	      \
      {									      \
	/* Surrogate characters in UCS-4 input are not valid.		      \
	   We must catch this, because the UCS-2 output might be	      \
	   interpreted as UTF-16 by other programs.  If we let		      \
	   surrogates pass through, attackers could make a security	      \
	   hole exploit by synthesizing any desired plane 1-16		      \
	   character.  */						      \
	result = __GCONV_ILLEGAL_INPUT;					      \
	if (! ignore_errors_p ())					      \
	  break;							      \
	inptr += 4;							      \
	++*irreversible;						      \
	continue;							      \
      }									      \
    else								      \
      {									      \
	*((uint16_t *) outptr)++ = val;					      \
	inptr += 4;							      \
      }									      \
  }
#define LOOP_NEED_FLAGS

Reply to: