Last active
August 2, 2017 15:29
-
-
Save markmont/b5f1ee6b4c1c7a68b085bb3aae96e3b9 to your computer and use it in GitHub Desktop.
W^X test case using temporary file that is mmap()'d twice
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Run under Fedora 26 with SELinux enabled | |
# | |
# /tmp must not be mounted noexec for this to work. | |
# | |
[markmont@f26docker examples]$ sudo setsebool selinuxuser_execstack=off deny_execmem=on | |
[sudo] password for markmont: | |
[markmont@f26docker examples]$ gcc -o m2 m2.c | |
[markmont@f26docker examples]$ ./m2 | |
(dynamic) code returned 42 | |
[markmont@f26docker examples]$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* W^X test case based on | |
* https://www.akkadia.org/drepper/selinux-mem.html | |
* and | |
* https://stackoverflow.com/questions/28015876/what-do-i-have-to-do-to-execute-code-in-data-areas-segment-protection | |
*/ | |
#include <stdio.h> | |
#include <errno.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/mman.h> /* mmap(), mprotect() */ | |
static uint8_t code[] = { | |
0xB8,0x2A,0x00,0x00,0x00, /* mov eax,0x2a */ | |
0xC3, /* ret */ | |
}; | |
int main(void) | |
{ | |
const size_t len = sizeof(code); | |
char tmpfname[] = "/tmp/execmemXXXXXX"; | |
int fd = mkstemp(tmpfname); | |
if (fd == -1) { | |
perror("can't create execmem file"); | |
return 1; | |
} | |
if (unlink(tmpfname) == -1) { | |
perror("can't unlink execmem file"); | |
return 1; | |
} | |
if (ftruncate (fd, 1000) == -1) { | |
perror("can't truncate execmem file"); | |
return 1; | |
} | |
void *writep = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | |
if (writep==MAP_FAILED) { | |
fprintf(stderr, "mmap() writep failed\n"); | |
return 2; | |
} | |
void *execp = mmap(NULL, 4096, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0); | |
if (execp==MAP_FAILED) { | |
fprintf(stderr, "mmap() execp failed\n"); | |
return 2; | |
} | |
/* Copy it in (still not executable) */ | |
memcpy(writep, code, len); | |
/* Go! */ | |
int (*func)(void) = execp; | |
printf("(dynamic) code returned %d\n", func()); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment