Data Execution Prevention

Daniel Himmelein daniel.himmelein at googlemail.com
Tue Jun 28 05:06:37 EDT 2011


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}



More information about the linux-arm mailing list