From owner-freebsd-emulation@FreeBSD.ORG Tue Sep 19 00:09:24 2006 Return-Path: X-Original-To: emulation@freebsd.org Delivered-To: freebsd-emulation@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E3A2216A412 for ; Tue, 19 Sep 2006 00:09:23 +0000 (UTC) (envelope-from saper@SYSTEM.PL) Received: from mail01.ish.de (pip251.ish.de [80.69.98.251]) by mx1.FreeBSD.org (Postfix) with ESMTP id 462D543D46 for ; Tue, 19 Sep 2006 00:09:22 +0000 (GMT) (envelope-from saper@SYSTEM.PL) Received: from [81.210.201.87] (account saper@iesy.net HELO saperski.saper.info) by mail-fe-01.mail01.ish.de (CommuniGate Pro SMTP 5.0.6) with ESMTPSA id 76170517 for emulation@freebsd.org; Tue, 19 Sep 2006 02:09:20 +0200 Received: from [127.0.0.1] (saperski.saper.info [127.0.0.1]) by saperski.saper.info (8.13.8/8.13.8) with ESMTP id k8J09AvH005947 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Tue, 19 Sep 2006 02:09:12 +0200 (CEST) (envelope-from saper@SYSTEM.PL) Message-ID: <450F3525.5080305@SYSTEM.PL> Date: Tue, 19 Sep 2006 02:09:09 +0200 From: Marcin Cieslak User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.8.0.6) Gecko/20060912 SeaMonkey/1.0.4 MIME-Version: 1.0 To: emulation@freebsd.org Content-Type: multipart/mixed; boundary="------------020603020907000609080904" Cc: Subject: mmap(2) fingerprinting on amd64 X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Sep 2006 00:09:24 -0000 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 #include #include #include #include #include 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--