Date: Tue, 19 Sep 2006 02:09:09 +0200 From: Marcin Cieslak <saper@SYSTEM.PL> To: emulation@freebsd.org Subject: mmap(2) fingerprinting on amd64 Message-ID: <450F3525.5080305@SYSTEM.PL>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------020603020907000609080904 Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: 7bit Attached please find a very simple brute-force mmap(2) testing program. 1. It would be nice if somebody could run this on real amd64 linux machine. and under FreeBSD linuxolator on amd64 machine. Please mail results to me. 2. I don't know how to include simple test for PROT_EXEC behaviour (there should be at least one case more in the mapprots[] plus somehow execute something in the access_test(). -- << Marcin Cieslak // saper@system.pl >> --------------020603020907000609080904 Content-Type: text/plain; name="mmap_test.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mmap_test.c" #include <fcntl.h> #include <sys/mman.h> #include <errno.h> #include <setjmp.h> #include <signal.h> #include <stdio.h> struct intdesc { const int val; const char *desc; }; static char TESTFILE[] = "/tmp/test"; static sigjmp_buf env; static char nofile[] = "anonymous"; static char * mmap_test(int map_prot, int map_mode, int fd) { char *qp; qp = mmap(0, 1024, map_prot, map_mode, fd, 0); if (qp != MAP_FAILED) { printf("mmap OK "); return qp; } else { printf("mmap error (%d)", errno); return NULL; } }; static void unmap_test(void *ptr) { if (ptr != NULL) munmap(ptr, 1024); } static int sigsegv = 0; static int buserr = 0; static int othersig = 0; static void handle_sig(int sig) { switch(sig) { case SIGSEGV: sigsegv ++; break; case SIGBUS: buserr ++; break; default: othersig = sig; } siglongjmp(env, 1); } static void access_test(void *ptr) { char *qp = (char *)ptr; struct sigaction newsig = { .sa_handler = &handle_sig, .sa_flags = 0, .sa_mask = 0, }; struct sigaction oldsegv; struct sigaction oldbus; sigsegv = buserr = othersig = 0; sigaction(SIGSEGV, &newsig, &oldsegv); sigaction(SIGBUS, &newsig, &oldbus); printf("read: "); if (sigsetjmp(env, 1) == 0) { printf("0x%02x", qp[0]); } else { if (sigsegv) printf("sigsegv"); if (buserr) printf("buserr"); if (othersig) printf("sig%02d", othersig); }; sigsegv = buserr = othersig = 0; printf(" write: "); if (sigsetjmp(env, 1) == 0) { qp[0] = 'B'; printf("OK"); } else { if (sigsegv) { printf("sigsegv"); }; if (buserr) { printf("buserr"); }; } sigaction(SIGSEGV, &oldsegv, NULL); sigaction(SIGBUS, &oldbus, NULL); } static void run_cases(struct intdesc filemodes[], struct intdesc mapmodes[], struct intdesc mapprots[], char * (* mapfunc)(int, int, int), void (* accessfunc)(void *), void (* unmapfunc)(void *)) { struct intdesc *filemode, *map_mode, *map_prot; int fd, caseid, anon; void *region; caseid = 1; for (filemode = filemodes; filemode->desc != NULL; filemode++) for (map_mode = mapmodes; map_mode->desc != NULL; map_mode++) for (map_prot = mapprots; map_prot->desc != NULL; map_prot++) { if (filemode->desc != nofile) { anon = 0; if ((fd = open(TESTFILE, filemode->val, 0644)) < 0 ) { perror("open testfile"); return; }; } else { fd = -1; anon = MAP_ANON; } printf("%04d: mmap(0, 1024, %s, %s%s, ...)\n" " for filemode %s: ", caseid, map_prot->desc, anon ? "MAP_ANON|":"", map_mode->desc, filemode->desc); region = (*mapfunc)(map_prot->val, anon | map_mode->val, fd); if (region) { (*accessfunc)(region); (*unmapfunc)(region); }; caseid ++; if (fd > 0) close(fd); printf("\n"); }; } int main() { struct intdesc filemodes[] = { {O_RDONLY, "O_RDONLY"}, {O_WRONLY, "O_WRONLY"}, {O_RDWR, "O_RDWR"}, {-1, nofile}, {-1, NULL}, }; struct intdesc mapmodes[] = { #if 0 {0, "none"}, #endif {MAP_SHARED, "MAP_SHARED"}, {MAP_PRIVATE, "MAP_PRIVATE"}, {-1, NULL}, }; struct intdesc mapprots[] = { {PROT_NONE, "PROT_NONE"}, {PROT_READ, "PROT_READ"}, {PROT_WRITE, "PROT_WRITE"}, {PROT_READ|PROT_WRITE, "PROT_READ|PROT_WRITE"}, {-1, NULL}, }; char *qp; int fd, caseid, anon; fd = open(TESTFILE, O_CREAT|O_WRONLY, 0644); write(fd, "ABCD"); if (fd > -1) close(fd); run_cases(filemodes, mapmodes, mapprots, &mmap_test, &access_test, &unmap_test); }; --------------020603020907000609080904--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?450F3525.5080305>