pow() fails with a segmentation fault when executed from dynamically allocated memory
Ángel González
keisial@gmail.com
Sat Jan 28 14:37:00 GMT 2012
On 28/01/12 13:21, Carlos O'Donell wrote:
> IIUC you have a code trampoline in dynamically allocated memory
> which calls my_pow() and somtimes it segfaults?
>
> Rather than making me decode the trampoline by hand, could you
> please provide the assembly instructions for the trampoline?
>
> Is there any reason you wrote the trampoline out by hand?
>
> My preference would have been to write the trampoline in C,
> let the compiler compile it, dynamically allocate the memory,
> and then memcpy the trampoline into place. The alternative
> being: compile the trampoline from an assembly file which has
> two symbols that mark the start and the end of the trampoline.
> In either case you get the benefit of the assembler which will
> double check your encoding and warn you if you made a mistake.
> If you use a C compiler it's even better because you then are
> assured you didn't make a procedure-call error.
>
> Cheers,
> Carlos.
I get the same failing behavior in both testcases as the reporter.
I have rewritten the testcase with a struct + memcpy (see below).
This way it can be disassembled with objdump -D, which shows
> 0000000000600b50 <value>:
> 600b50: 49 bb c0 06 40 00 00 movabs $0x4006c0,%r11
> 600b57: 00 00 00
> 600b5a: 41 ff d3 callq *%r11
> 600b5d: c3 retq
> ...
0x4006c0 is the address asignated to my_pow. Disassembled below:
> 00000000004006c0 <my_pow>:
> 4006c0: 48 83 ec 18 sub $0x18,%rsp
> 4006c4: bf ec 07 40 00 mov $0x4007ec,%edi
> 4006c9: e8 22 fe ff ff callq 4004f0 <puts@plt>
> 4006ce: f2 0f 10 0d 42 01 00 movsd 0x142(%rip),%xmm1
> # 400818 <_IO_stdin_used+0x30>
> 4006d5: 00
> 4006d6: f2 0f 10 05 42 01 00 movsd 0x142(%rip),%xmm0
> # 400820 <_IO_stdin_used+0x38>
> 4006dd: 00
> 4006de: e8 3d fe ff ff callq 400520 <pow@plt>
> 4006e3: bf f1 07 40 00 mov $0x4007f1,%edi
> 4006e8: f2 0f 11 04 24 movsd %xmm0,(%rsp)
> 4006ed: e8 fe fd ff ff callq 4004f0 <puts@plt>
> 4006f2: f2 0f 10 04 24 movsd (%rsp),%xmm0
> 4006f7: 48 83 c4 18 add $0x18,%rsp
> 4006fb: c3 retq
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <sys/mman.h>
volatile double my_pow() {
printf("test\n");
double ret = pow(-2.0, 0.5);
printf("test2\n");
return ret;
}
struct {
char a, b;
void *addr;
char c, d, e, f;
} __attribute__((packed)) value = { 0x49, 0xBB, &my_pow, 0x41, 0xff,
0xd3, 0xc3 };
void execute() {
uint8_t *code = ( uint8_t * ) mmap( NULL, 1024,
PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0,
0 );
memcpy(code, &value, sizeof(value));
double (*fun)(void) = (double (*)(void))code;
printf("value is at %p\n", &value);
printf("Result: %f\n", my_pow());
printf("Result: %f\n", fun());
}
int main() {
execute();
return 0;
}
More information about the Libc-help
mailing list