From cf113d392a1557457b3c82025c3f6797a85b4d01 Mon Sep 17 00:00:00 2001 From: "Shiratori, Takehiro" Date: Wed, 21 Nov 2018 17:24:29 +0900 Subject: [PATCH] Test "/proc/PID/maps support add" on arm64. Change-Id: I0585ae6257b5c0269760dd7f23ba75b83dd7ac2c --- test/proc_maps/arm64/Makefile | 15 ++ test/proc_maps/arm64/README | 58 +++++++ test/proc_maps/arm64/proc_maps.c | 254 +++++++++++++++++++++++++++++++ test/proc_maps/arm64/result.log | 28 ++++ test/proc_maps/arm64/run.sh | 9 ++ 5 files changed, 364 insertions(+) create mode 100644 test/proc_maps/arm64/Makefile create mode 100644 test/proc_maps/arm64/README create mode 100644 test/proc_maps/arm64/proc_maps.c create mode 100644 test/proc_maps/arm64/result.log create mode 100755 test/proc_maps/arm64/run.sh diff --git a/test/proc_maps/arm64/Makefile b/test/proc_maps/arm64/Makefile new file mode 100644 index 00000000..ea078233 --- /dev/null +++ b/test/proc_maps/arm64/Makefile @@ -0,0 +1,15 @@ +# Makefile COPYRIGHT FUJITSU LIMITED 2018 +CC = gcc +TARGET = proc_maps +LDFLAGS = + +all: $(TARGET) + +proc_maps: proc_maps.c + $(CC) -o $@ $^ $(LDFLAGS) + +test: all + ./run.sh + +clean: + rm -f $(TARGET) diff --git a/test/proc_maps/arm64/README b/test/proc_maps/arm64/README new file mode 100644 index 00000000..a82665fa --- /dev/null +++ b/test/proc_maps/arm64/README @@ -0,0 +1,58 @@ +/* README COPYRIGHT FUJITSU LIMITED 2018 */ + +/proc/[pid]/maps 追加機能テストセットREADME + +(1) テストの実行方法 + 以下の手順でテストを実行する + 1. $HOME/.mck_test_configを用意する + 当該ファイルは、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを + $HOMEにコピーし、適宜編集する + 2. make testを実行する + +(2) テスト項目詳細 + TEST001 ---p の属性でmmap登録した情報が出力されること。 + TEST002 ---s の属性でmmap登録した情報が出力されること。 + TEST003 r--p の属性でmmap登録した情報が出力されること。 + TEST004 r--s の属性でmmap登録した情報が出力されること。 + TEST005 -w-p の属性でmmap登録した情報が出力されること。 + TEST006 -w-s の属性でmmap登録した情報が出力されること。 + TEST007 --xp の属性でmmap登録した情報が出力されること。 + TEST008 --xs の属性でmmap登録した情報が出力されること。 + TEST009 rw-p の属性でmmap登録した情報が出力されること。 + TEST010 rw-s の属性でmmap登録した情報が出力されること。 + TEST011 r-xp の属性でmmap登録した情報が出力されること。 + TEST012 r-xs の属性でmmap登録した情報が出力されること。 + TEST013 -wxp の属性でmmap登録した情報が出力されること。 + TEST014 -wxs の属性でmmap登録した情報が出力されること。 + TEST015 rwxp の属性でmmap登録した情報が出力されること。 + TEST016 rwxs の属性でmmap登録した情報が出力されること。 + TEST017 offsetフィールドが全て0であること。 + TEST018 devフィールドがすべて0:0であること。 + TEST019 inodeフィールドが全て0であること。 + TEST020 "[vdso]"のpathnameを持つエントリが存在すること。 + TEST021 "[vsyscall]"のpathnameを持つエントリが存在すること。 + TEST022 "[stack]"のpathnameを持つエントリのstart-endの間にスタックアドレスがあること。 + TEST023 "[heap]"のpathnameを持つエントリのstart-endの間にsbrk()の結果アドレスがあること。 + TEST024 pathnameが空文字列であるエントリがあること。 + +(3) 実行結果ログ + result.logファイル内に実行時のログを記載する。 + 実行に利用したIHK/McKernelは、IA版における下記の版数相当の + arm64版移植IHK/McKernelである。 + + IHK + commit d6fcbee8cb91f9ec4b49f97c918e696ac0335aaf + Author: Shiratori, Takehiro + Date: Tue Oct 16 16:25:33 2018 +0900 + + McKernel + commit 6f9fef2b13447c74c36d15cf5ebd186f8395ccca + Author: Ken Sato + Date: Tue Sep 25 10:05:41 2018 +0900 + +(4) 備考 + 本テストセットは一部IHK/McKernelの実装挙動を期待としてテスト項目を作成しているため、 + 全ての項目がHOST-Linux上でもOKになるとは限らない。 + + +以上。 diff --git a/test/proc_maps/arm64/proc_maps.c b/test/proc_maps/arm64/proc_maps.c new file mode 100644 index 00000000..af30852b --- /dev/null +++ b/test/proc_maps/arm64/proc_maps.c @@ -0,0 +1,254 @@ +/* proc_maps.c COPYRIGHT FUJITSU LIMITED 2018 */ +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 4096 +#define EXP_STR_SIZE 64 + +int main(int argc, char *argv[]) +{ + FILE *fp = NULL; + const char pfname[] = "/proc/self/maps"; + int result = 0; + int i = 0; + int offset_ng = 0; + int dev_ng = 0; + int inode_ng = 0; + int vdso_ok = 0; + int vsyscall_ok = 0; + int stack_ok = 0; + int heap_ok = 0; + int pathempty_ok = 0; + const unsigned int page_size = sysconf(_SC_PAGESIZE); + char buf[BUF_SIZE]; + + struct { + int okng; + int prot; + int flags; + void *addr; + char exp[EXP_STR_SIZE]; + } mapconf[] = { + { -1, PROT_NONE, MAP_PRIVATE }, + { -1, PROT_NONE, MAP_SHARED }, + { -1, PROT_READ, MAP_PRIVATE }, + { -1, PROT_READ, MAP_SHARED }, + { -1, PROT_WRITE, MAP_PRIVATE }, + { -1, PROT_WRITE, MAP_SHARED }, + { -1, PROT_EXEC, MAP_PRIVATE }, + { -1, PROT_EXEC, MAP_SHARED }, + { -1, PROT_READ | PROT_WRITE, MAP_PRIVATE }, + { -1, PROT_READ | PROT_WRITE, MAP_SHARED }, + { -1, PROT_READ | PROT_EXEC, MAP_PRIVATE }, + { -1, PROT_READ | PROT_EXEC, MAP_SHARED }, + { -1, PROT_WRITE | PROT_EXEC, MAP_PRIVATE }, + { -1, PROT_WRITE | PROT_EXEC, MAP_SHARED }, + { -1, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE }, + { -1, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED }, + }; + + /* fopen */ + if ((fp = fopen(pfname, "r")) == NULL) { + printf("fopen() failed. %d\n", errno); + result = -1; + goto fast_err; + } + + /* mapping */ + for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) { + mapconf[i].addr = mmap(NULL, page_size, mapconf[i].prot, + mapconf[i].flags | MAP_ANONYMOUS, -1, 0); + if (mapconf[i].addr == NULL) { + printf("mmap(prot=%d, flags=%d) failed. %d\n", + mapconf[i].prot, mapconf[i].flags, errno); + result = -1; + goto err; + } + snprintf(mapconf[i].exp, sizeof(mapconf[i].exp), + "%lx-%lx %s%s%s%s", mapconf[i].addr, mapconf[i].addr + page_size, + mapconf[i].prot & PROT_READ ? "r" : "-", + mapconf[i].prot & PROT_WRITE ? "w" : "-", + mapconf[i].prot & PROT_EXEC ? "x" : "-", + mapconf[i].flags & MAP_PRIVATE ? "p" : "s"); + } + + /* print-procfs */ + while (fgets(buf, sizeof(buf), fp) != NULL) { + unsigned long start; + unsigned long end; + char prot[8]; + unsigned long offset = 1; + unsigned long dev1 = 1; + unsigned long dev2 = 1; + unsigned long inode = 1; + char pathname[BUF_SIZE] = "\0"; + + sscanf(buf, "%lx-%lx %s %lx %lx:%lx %lx\t\t\t%s", + &start, &end, prot, &offset, &dev1, &dev2, &inode, pathname); + + if (offset != 0) { + offset_ng = 1; + } + + if (dev1 != 0 || dev2 != 0) { + dev_ng = 1; + } + + if (inode != 0) { + inode_ng = 1; + } + + if (strlen(pathname) != 0) { + if (vdso_ok != 1) { + if (!strcmp("[vdso]", pathname)) { + vdso_ok = 1; + } + } + + if (vsyscall_ok != 1) { + if (!strcmp("[vsyscall]", pathname)) { + vsyscall_ok = 1; + } + } + + if (stack_ok != 1) { + if (!strcmp("[stack]", pathname)) { + unsigned long stack_addr = (unsigned long)pathname; + stack_addr--; + + if ((start <= stack_addr) && + (stack_addr < end)) { + stack_ok = 1; + } else { + stack_ok = -1; + } + } + } + + if (heap_ok != 1) { + if (!strcmp("[heap]", pathname)) { + unsigned long heap_addr = (unsigned long)sbrk(0); + heap_addr--; + + if ((start <= heap_addr) && + (heap_addr < end)) { + heap_ok = 1; + } else { + heap_ok = -1; + } + } + } + } else if (pathempty_ok != 1) { + pathempty_ok = 1; + } + + for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) { + if (mapconf[i].okng == -1) { + if (strstr(buf, mapconf[i].exp)) { + mapconf[i].okng = 0; + break; + } + } + } + } + + /* unmapping */ + for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) { + munmap(mapconf[i].addr, page_size); + } + + /* ok/ng check */ + /* addr, prot and flags */ + for (i = 0; i < sizeof(mapconf) / sizeof(mapconf[0]); i++) { + if (mapconf[i].okng == -1) { + printf("TEST%03d: NG, %s not found.\n", i + 1, mapconf[i].exp); + result = -1; + } else { + printf("TEST%03d: OK\n", i + 1); + } + } + + /* offset */ + if (offset_ng == 1) { + printf("TEST%03d: NG, offset field is not 0.\n", ++i); + result = -1; + } else { + printf("TEST%03d: OK\n", ++i); + } + + /* dev */ + if (dev_ng == 1) { + printf("TEST%03d: NG, dev field is not 0.\n", ++i); + result = -1; + } else { + printf("TEST%03d: OK\n", ++i); + } + + /* inode */ + if (inode_ng == 1) { + printf("TEST%03d: NG, inode field is not 0.\n", ++i); + result = -1; + } else { + printf("TEST%03d: OK\n", ++i); + } + + /* pathname */ + /* [vsdo] */ + if (vdso_ok == 1) { + printf("TEST%03d: OK\n", ++i); + } else { + printf("TEST%03d: NG, [vdso] pathname not found.\n", ++i); + result = -1; + } + + /* [vsyscall] */ + if (vsyscall_ok == 1) { + printf("TEST%03d: OK\n", ++i); + } else { + printf("TEST%03d: NG, [vsyscall] pathname not found.\n", ++i); + result = -1; + } + + /* [stack] */ + if (stack_ok == 0) { + printf("TEST%03d: NG, [stack] pathname not found.\n", ++i); + result = -1; + } else if (stack_ok == -1) { + printf("TEST%03d: NG, [stack] pathname found, but addr is not expected.\n", ++i); + result = -1; + } else { + printf("TEST%03d: OK\n", ++i); + } + + /* [heap] */ + if (heap_ok == 0) { + printf("TEST%03d: NG, [heap] pathname not found.\n", ++i); + result = -1; + } else if (heap_ok == -1) { + printf("TEST%03d: NG, [heap] pathname found, but addr is not expected.\n", ++i); + result = -1; + } else { + printf("TEST%03d: OK\n", ++i); + } + + /* empty */ + if (pathempty_ok == 0) { + printf("TEST%03d: NG, empty pathname not found.\n", ++i); + result = -1; + } else { + printf("TEST%03d: OK\n", ++i); + } + +err: + if (fclose(fp)) { + printf("fclose() failed. %d\n", errno); + result = -1; + } + +fast_err: + return result; +} diff --git a/test/proc_maps/arm64/result.log b/test/proc_maps/arm64/result.log new file mode 100644 index 00000000..3d8ffca4 --- /dev/null +++ b/test/proc_maps/arm64/result.log @@ -0,0 +1,28 @@ +gcc -o proc_maps proc_maps.c +./run.sh +mcstop+release.sh ... done +mcreboot.sh -c 4-7 -m 2G ... done +TEST001: OK +TEST002: OK +TEST003: OK +TEST004: OK +TEST005: OK +TEST006: OK +TEST007: OK +TEST008: OK +TEST009: OK +TEST010: OK +TEST011: OK +TEST012: OK +TEST013: OK +TEST014: OK +TEST015: OK +TEST016: OK +TEST017: OK +TEST018: OK +TEST019: OK +TEST020: OK +TEST021: OK +TEST022: OK +TEST023: OK +TEST024: OK diff --git a/test/proc_maps/arm64/run.sh b/test/proc_maps/arm64/run.sh new file mode 100755 index 00000000..3b559217 --- /dev/null +++ b/test/proc_maps/arm64/run.sh @@ -0,0 +1,9 @@ +#!/bin/sh +## run.sh COPYRIGHT FUJITSU LIMITED 2018 ## + +USELTP=0 +USEOSTEST=0 + +. ../../common.sh + +${MCEXEC} ./proc_maps