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

Bug#593558: libffi-dev: ffi_call segfault: read beyond the heap, allocated for return value



ret value must be 10 for strnlen, and 5 for u8_mbsnlen;

I've slightly modified the strlen.c from testsuite/libffi.call; in the
same manner I've replaced return value type ffi_type_sint with a
"structured" type of the size sizeof(size_t). Test interrupts since
then:

$ ./a.out 
check new
check new->elements
check ffi_arg
init
size of the structure
check 1
Aborted

All right when return value of ffi_type_sint (comment out rows ##42, 45
and uncomment ##43, 46):

$ ./a.out 
check new
check new->elements
check ffi_arg
init
size of the structure
check 1
check 7
check 25

There's no problem on x86_64 as well.

> tag 593558 + moreinfo
> thanks
> 
> On 19.08.2010 10:48, Ygrex wrote:
> > Package: libffi-dev
> > Version: 3.0.9-2
> > Severity: important
> >
> > The test C-code is attached:
> > gcc-4.4 -lffi -lunistring -o test test.c
> >
> > It can be compiled without libunistring as well (see notes, please):
> > 1. comment out rows #7 and #8
> > 2. uncomment #9
> > 3. gcc-4.4 -lffi -o test test.c
> >
> > What the code does:
> > 1. creates a new ffi_type to emulate size_t;
> > 2. allocates array of types of function arguments: (char *) and
> > (size_t); 3. prepare CIF to call the size_t function with two
> > arguments; 4. allocates array of pointers to two arguments: char *b
> > and size_t a; 5. runs ffi_call and segfaults;
> 
> unable to reproduce on i386 unstable (without the library):
> 
> $ valgrind --track-origins=yes -q ./a.out
> just before...
> ==13621== Conditional jump or move depends on uninitialised value(s)
> ==13621==    at 0x48DC040: strnlen (mc_replace_strmem.c:263)
> ==13621==    by 0x48FB54E: ffi_call_SYSV
> (in /usr/lib/libffi.so.5.0.10) ==13621==    by 0x48FB38D: ffi_call
> (in /usr/lib/libffi.so.5.0.10) ==13621==    by 0x80488FC: main
> (test.c:71) ==13621==  Uninitialised value was created by a heap
> allocation ==13621==    at 0x48DAF50: malloc (vg_replace_malloc.c:236)
> ==13621==    by 0x8048842: main (test.c:55)
> ==13621==
> right after!
> ==13621== Use of uninitialised value of size 4
> ==13621==    at 0x49390FE: _itoa_word (_itoa.c:195)
> ==13621==    by 0x493C8EF: vfprintf (vfprintf.c:1613)
> ==13621==    by 0x4943FAF: printf (printf.c:35)
> ==13621==    by 0x804891F: main (test.c:80)
> ==13621==  Uninitialised value was created by a heap allocation
> ==13621==    at 0x48DAF50: malloc (vg_replace_malloc.c:236)
> ==13621==    by 0x8048842: main (test.c:55)
> ==13621==
> ==13621== Conditional jump or move depends on uninitialised value(s)
> ==13621==    at 0x4939106: _itoa_word (_itoa.c:195)
> ==13621==    by 0x493C8EF: vfprintf (vfprintf.c:1613)
> ==13621==    by 0x4943FAF: printf (printf.c:35)
> ==13621==    by 0x804891F: main (test.c:80)
> ==13621==  Uninitialised value was created by a heap allocation
> ==13621==    at 0x48DAF50: malloc (vg_replace_malloc.c:236)
> ==13621==    by 0x8048842: main (test.c:55)
> ==13621==
> ret value: 0
> 


-- 
С уважением,

Igor Bogomazov
Игорь Богомазов
Главный технический специалист
HighLink Ltd. St-Petersburg, Russia
8(812)334-12-12 [доб. 220]
8(931)238-94-41 (Мегафон)
http://www.hl.ru

#include <stdlib.h>
#include <string.h>
#include <ffi.h>

#define MAX_ARGS 256
#define CHECK(x) !(x) ? abort() : 0

static size_t my_strlen(char *s)
{
  return (strlen(s));
}

int main (void)
{
	ffi_type *new = malloc(sizeof(ffi_type));
	puts("check new");
	CHECK(new);
	new->size = new->alignment = 0;
	new->type = FFI_TYPE_STRUCT;
	new->elements = calloc(5, sizeof(ffi_type *));
	puts("check new->elements");
	CHECK(new->elements);
	new->elements[0] = &ffi_type_uchar;
	new->elements[1] = &ffi_type_uchar;
	new->elements[2] = &ffi_type_uchar;
	new->elements[3] = &ffi_type_uchar;
	new->elements[4] = NULL;
  ffi_cif cif;
  ffi_type *args[MAX_ARGS];
  void *values[MAX_ARGS];
  ffi_arg rint;
	puts("check ffi_arg");
	CHECK(sizeof(ffi_arg) == 4);
  char *s;

  args[0] = &ffi_type_pointer;
  values[0] = (void*) &s;
  
  /* Initialize the cif */
	puts("init");
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		     new, args) == FFI_OK);
//		     &ffi_type_sint, args) == FFI_OK);
	puts("size of the structure");
	CHECK(new->size == 4);
//	CHECK(ffi_type_sint.size == 4);
  
  s = "a";
  ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
	puts("check 1");
  CHECK(rint == 1);
  
  s = "1234567";
  ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
	puts("check 7");
  CHECK(rint == 7);
  
  s = "1234567890123456789012345";
  ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
	puts("check 25");
  CHECK(rint == 25);
  
  exit (0);
}
  

Attachment: signature.asc
Description: PGP signature


Reply to: