pow() fails with a segmentation fault when executed from dynamically allocated memory

Lars Magnusson lavima@gmail.com
Sat Jan 28 09:17:00 GMT 2012


Hello

I'm having some trouble executing pow() from dynamically allocated
memory. The memory is allocated with mmap() and filled with x86-64
instructions. This seems to work fine for the most part, but it fails
with a segmentation fault when I try to invoke the pow function with x
< 0 and y non-integer (which should return NaN).

I've reduced the problem down to the following code:

double my_pow() {
  printf("test\n");
  double ret = pow(-2.0, 0.5);
  printf("test2\n");
  return ret;
}

void execute() {

  uint8_t *code = ( uint8_t * ) mmap( NULL, 1024,
    PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0 );

  code[0] = 0x49; code[1] = 0xbb;

  uint64_t addr = (uint64_t)&my_pow;
  code[2] = addr % 0x100; code[3] = (addr % 0x10000) >> 8;
  code[4] = (addr % 0x1000000) >> 16; code[5] = (addr % 0x100000000) >> 24;
  code[6] = (addr % 0x10000000000) >> 32; code[7] = (addr %
0x1000000000000) >> 40;
  code[8] = (addr % 0x100000000000000) >> 48; code[9] = addr >> 56;

  code[10] = 0x41; code[11] = 0xff; code[12] = 0xd3; code[13] = 0xc3;

  double (*fun)(void) = (double (*)(void))code;

  printf("Result: %f\n", my_pow());
  printf("Result: %f\n", fun());
}

The normal invocation of my_pow works fine, but it fails with
segmentation fault from the the dynamic code on my machine with glibc
version 2.13. The code executes without trouble in both instances on
an older system with version 2.5 of glibc.

My initial thought was that this was a kernel issues (which also
differs between the systems), but I wanted to hear what you think
before moving on.

Kind regards
Lars Vidar Magnusson



More information about the Libc-help mailing list