Discussion:
Data Execution Prevention
Daniel Himmelein
2011-06-28 09:06:37 UTC
Permalink
I wrote a simple data execution prevention (DEP) test to check if my
DEP patch for ARM Linux is working and to also check the PaX patch.
This worked pretty fine, but my test program crashes with a SIGSEGV in
50% of the test runs. In the other cases the tests work perfectly.
I don't know why my test does not always succeed. I already tried to
clear the instruction cache. But this did not help either.
I tried the same on the x86. There it does always work perfectly. But
it also has a common instruction and data cache. Maybe that has to do
with the problem.

Any ideas?

Here is my test code:

DepTest.cpp:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>

extern "C" uint32_t jmpToCode(uint32_t address);

int main()
{
void* data = new uint32_t[4096];

uint32_t* code = (uint32_t*) data;
// arm-eabi-objdump -d Test
// code[0] = 0xef9f0002; // endless loop
code[0] = 0xe320f000; // nop
code[1] = 0xe320f000; // nop
code[2] = 0xe320f000; // nop
code[3] = 0xe320f000; // nop
code[4] = 0xe320f000; // nop
code[5] = 0xe320f000; // nop
code[6] = 0xe320f000; // nop
code[7] = 0xe1a0f00e; // jump back to calling function -> mov pc, lr

printf("DEP-Test (1): 0x%X: 0x%X\n", code, code[0]);
uint32_t rc = jmpToCode((uint32_t)code);
printf("DEP-Test (2): 0x%X 0x%X: 0x%X\n", rc, code, code[0]);

return 0;
}

Utils.S:
.text

# The first 4 args are passed via r0 to r3
# The return code is always in r0
# pc points to the next instruction to be fetched, not to the
instructing that will be executed next
# - in ARM state, the pc always points to the address of the
instruction plus 8 bytes
# - in Thumb state, the pc is the instruction address plus 4 bytes

.code 32
.align 4
.global jmpToCode
jmpToCode:
push {ip, lr}
mov lr, pc @ lr points to the "mov r0, ..." command
mov pc, r0
mov r0, r0
pop {ip, pc}
Russell King - ARM Linux
2011-06-28 09:46:50 UTC
Permalink
Post by Daniel Himmelein
I wrote a simple data execution prevention (DEP) test to check if my
DEP patch for ARM Linux is working and to also check the PaX patch.
This worked pretty fine, but my test program crashes with a SIGSEGV in
50% of the test runs. In the other cases the tests work perfectly.
I don't know why my test does not always succeed. I already tried to
clear the instruction cache. But this did not help either.
How did you try to do that?
Post by Daniel Himmelein
I tried the same on the x86. There it does always work perfectly. But
it also has a common instruction and data cache. Maybe that has to do
with the problem.
You are correct.

On ARM, you need to use the cacheflush kernel syscall to ensure that
data written is visible to the instruction stream due to the cache
architecture.

Continue reading on narkive:
Loading...