From c371fbf13b2103d4b81dcf195e4059c5c1fe936c Mon Sep 17 00:00:00 2001 From: Ken Sato Date: Fri, 30 Aug 2019 13:46:06 +0900 Subject: [PATCH] file map: cause SIGBUS when access to a page beyond EOF Change-Id: Iaf7d792413e674267fd1c05c382212c8f67d8f5b Refs: #1291 --- executer/kernel/mcctrl/syscall.c | 19 ++++++- test/issues/1291/C1291.sh | 62 ++++++++++++++++++++++ test/issues/1291/Makefile | 11 ++++ test/issues/1291/README | 41 +++++++++++++++ test/issues/1291/aarch64_result.log | 77 +++++++++++++++++++++++++++ test/issues/1291/map_and_read.c | 50 ++++++++++++++++++ test/issues/1291/x86_64_result.log | 82 +++++++++++++++++++++++++++++ 7 files changed, 341 insertions(+), 1 deletion(-) create mode 100755 test/issues/1291/C1291.sh create mode 100644 test/issues/1291/Makefile create mode 100644 test/issues/1291/README create mode 100644 test/issues/1291/aarch64_result.log create mode 100644 test/issues/1291/map_and_read.c create mode 100644 test/issues/1291/x86_64_result.log diff --git a/executer/kernel/mcctrl/syscall.c b/executer/kernel/mcctrl/syscall.c index 16dcf09b..69ffd0f8 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1153,8 +1154,9 @@ static int pager_req_read(ihk_os_t os, uintptr_t handle, off_t off, size_t size, uintptr_t phys = -1; ihk_device_t dev = ihk_os_to_dev(os); void *buf = NULL; - loff_t pos; + loff_t pos, fsize; unsigned long flags; + unsigned int major, minor; dprintk("pager_req_read(%lx,%lx,%lx,%lx)\n", handle, off, size, rpa); @@ -1176,6 +1178,21 @@ static int pager_req_read(ihk_os_t os, uintptr_t handle, off_t off, size_t size, goto out; } + major = MAJOR(file->f_mapping->host->i_rdev); + minor = MINOR(file->f_mapping->host->i_rdev); + if ((major == 1 && minor == 1) || // /dev/mem + (major == 1 && minor == 5)) { // /dev/zero + /* Nothing to check */ + } + else { + /* Check if the target page fits in the file */ + fsize = i_size_read(file->f_mapping->host); + if (off > fsize) { + ss = 0; + goto out; + } + } + phys = ihk_device_map_memory(dev, rpa, size); buf = ihk_device_map_virtual(dev, phys, size, NULL, 0); if (!buf) { diff --git a/test/issues/1291/C1291.sh b/test/issues/1291/C1291.sh new file mode 100755 index 00000000..fb9a63f1 --- /dev/null +++ b/test/issues/1291/C1291.sh @@ -0,0 +1,62 @@ +#/bin/sh + +USELTP=1 +USEOSTEST=0 + +. ../../common.sh + +issue=1291 +tid=01 + +tname=`printf "C${issue}T%02d" ${tid}` +echo "*** ${tname} start *******************************" +tp=mmap13 +sudo $MCEXEC $LTPBIN/${tp} 2>&1 | tee $tp.txt +ok=`grep TPASS $tp.txt | wc -l` +ng=`grep TFAIL $tp.txt | wc -l` +if [ $ng = 0 ]; then + echo "*** ${tname} PASSED ($ok)" +else + echo "*** ${tname} FAILED (ok=$ok ng=%ng)" +fi +let tid++ +echo "" + +for devf in /dev/mem /dev/zero +do + tname=`printf "C${issue}T%02d" ${tid}` + echo "*** ${tname} start *******************************" + if [ ! -e $devf ]; then + echo "$devf is not exist" + echo "*** ${tname} SKIP" + let tid++ + echo "" + continue + fi + sudo $MCEXEC ./map_and_read ${devf} + if [ $? = 0 ]; then + echo "*** ${tname} PASSED" + else + echo "*** ${tname} FAILED" + fi + let tid++ + echo "" +done + +for tp in mmap01 mmap02 mmap03 mmap04 mmap05 mmap06 mmap07 mmap08 \ +mmap09 mmap12 mmap14 mmap15 +do + tname=`printf "C${issue}T%02d" ${tid}` + echo "*** ${tname} start *******************************" + sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt + ok=`grep TPASS $tp.txt | wc -l` + ng=`grep TFAIL $tp.txt | wc -l` + if [ $ng = 0 ]; then + echo "*** ${tname} PASSED ($ok)" + else + echo "*** ${tname} FAILED (ok=$ok ng=%ng)" + fi + let tid++ + echo "" +done + diff --git a/test/issues/1291/Makefile b/test/issues/1291/Makefile new file mode 100644 index 00000000..ca64fe97 --- /dev/null +++ b/test/issues/1291/Makefile @@ -0,0 +1,11 @@ +CFLAGS=-g +LDFLAGS= + +TARGET=map_and_read + +all: $(TARGET) + +test: all + ./C1291.sh +clean: + rm -f $(TARGET) *.o *.txt diff --git a/test/issues/1291/README b/test/issues/1291/README new file mode 100644 index 00000000..385135ae --- /dev/null +++ b/test/issues/1291/README @@ -0,0 +1,41 @@ +【Issue#1291 動作確認】 +□ テスト内容 +1. Issueで報告された再現プログラムで現象が再現しないことを確認 +C1291T01: LTP mmap13 + ファイルマップした後、EOFが存在するページより後のページにアクセスした際に + SIGBUSが発生することを確認するテスト + mmap13がPASSすることを確認する + +2. デバイスファイルではSIGBUSが発生しないことを確認 + ファイルマップ可能な/dev/mem, /dev/zero について、 + 2ページ分のファイルマップを行う。 + その後、それぞれのページにアクセスしてもSIGBUSが + 発生しないことを確認する +C1291T02: /dev/mem での確認 +C1291T03: /dev/zero での確認 + +3. 以下のLTPを用いて既存のmmap機能に影響が無いことを確認 + - mmap01 + - mmap02 + - mmap03 + - mmap04 + - mmap05 + - mmap06 + - mmap07 + - mmap08 + - mmap09 + - mmap12 + - mmap14 + - mmap15 + +□ 実行手順 +$ make test + +McKernelのインストール先や、OSTEST, LTPの配置場所は、 +$HOME/.mck_test_config を参照している +.mck_test_config は、McKernelをビルドした際に生成されるmck_test_config.sample ファイルを +$HOMEにコピーし、適宜編集する + +□ 実行結果 +result_x86_64.log および result_aarch64.log 参照。 +すべての項目をPASSしていることを確認。 diff --git a/test/issues/1291/aarch64_result.log b/test/issues/1291/aarch64_result.log new file mode 100644 index 00000000..4fc7d80c --- /dev/null +++ b/test/issues/1291/aarch64_result.log @@ -0,0 +1,77 @@ +*** C1291T01 start ******************************* +mmap13 1 TPASS : Got SIGBUS as expected +*** C1291T01 PASSED (1) + +*** C1291T02 start ******************************* +/dev/mem is not exist +*** C1291T02 SKIP + +*** C1291T03 start ******************************* +** FileMap(2pages) /dev/zero and read +value: 0x0 +Touch head of 1st page: OK +value: 0x0 +Touch middle of 1st page: OK +value: 0x0 +Touch middle of 2nd page: OK +*** C1291T03 PASSED + +*** C1291T04 start ******************************* +sh: line 1: 26262 Segmentation fault grep XYZ /tmp/mmaADcyci/mmapfile > /dev/null +mmap01 1 TPASS : Functionality of mmap() successful +*** C1291T04 PASSED (1) + +*** C1291T05 start ******************************* +mmap02 1 TPASS : Functionality of mmap() successful +*** C1291T05 PASSED (1) + +*** C1291T06 start ******************************* +mmap03 1 TPASS : mmap() functionality is correct +*** C1291T06 PASSED (1) + +*** C1291T07 start ******************************* +mmap04 1 TPASS : Functionality of mmap() successful +*** C1291T07 PASSED (1) + +*** C1291T08 start ******************************* +mmap05 1 TPASS : Got SIGSEGV as expected +*** C1291T08 PASSED (1) + +*** C1291T09 start ******************************* +mmap06 1 TPASS : mmap failed with EACCES +*** C1291T09 PASSED (1) + +*** C1291T10 start ******************************* +mmap07 1 TPASS : mmap failed with EACCES +*** C1291T10 PASSED (1) + +*** C1291T11 start ******************************* +mmap08 1 TPASS : mmap failed with EBADF +*** C1291T11 PASSED (1) + +*** C1291T12 start ******************************* +mmap09 1 TPASS : ftruncate mmaped file to a smaller size +mmap09 2 TPASS : ftruncate mmaped file to a larger size +mmap09 3 TPASS : ftruncate mmaped file to 0 size +*** C1291T12 PASSED (3) + +*** C1291T13 start ******************************* +tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s +mmap12.c:103: INFO: All pages are present +mmap12.c:127: PASS: File mapped properly + +Summary: +passed 1 +failed 0 +skipped 0 +warnings 0 +*** C1291T13 PASSED (0) + +*** C1291T14 start ******************************* +mmap14 1 TPASS : Functionality of mmap() successful +*** C1291T14 PASSED (1) + +*** C1291T15 start ******************************* +mmap15 1 TPASS : mmap into high region failed as expected: errno=ENOMEM(12): Cannot allocate memory +*** C1291T15 PASSED (1) + diff --git a/test/issues/1291/map_and_read.c b/test/issues/1291/map_and_read.c new file mode 100644 index 00000000..3e810eab --- /dev/null +++ b/test/issues/1291/map_and_read.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include + +#define TEST_TEXT "Test Text" + +int main(int argc, char *argv[]) +{ + int fd; + long pgsize = getpagesize(); + void *addr; + int rc = 0; + char *ch; + + if (argc < 2) { + printf("ERROR: too few arguments\n"); + return -1; + } + + printf("** FileMap(2pages) %s and read\n", argv[1]); + if ((fd = open(argv[1], O_RDONLY)) == -1) { + perror("open"); + exit(-1); + } + + addr = mmap(0, pgsize * 2, PROT_READ, MAP_FILE | MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + perror("mmap"); + return -1; + } + + ch = addr; + printf("value: 0x%lx\n", (unsigned long)*ch); + printf("Touch head of 1st page: OK\n"); + + ch = addr + (pgsize / 2) + 64; + printf("value: 0x%lx\n", (unsigned long)*ch); + printf("Touch middle of 1st page: OK\n"); + + ch = addr + pgsize + 64; + printf("value: 0x%lx\n", (unsigned long)*ch); + printf("Touch middle of 2nd page: OK\n"); + + munmap(addr, pgsize * 2); + close(fd); +} diff --git a/test/issues/1291/x86_64_result.log b/test/issues/1291/x86_64_result.log new file mode 100644 index 00000000..590b6613 --- /dev/null +++ b/test/issues/1291/x86_64_result.log @@ -0,0 +1,82 @@ +*** C1291T01 start ******************************* +mmap13 1 TPASS : Got SIGBUS as expected +*** C1291T01 PASSED (1) + +*** C1291T02 start ******************************* +** FileMap(2pages) /dev/mem and read +value: 0xfffffffffffffff3 +Touch head of 1st page: OK +value: 0x0 +Touch middle of 1st page: OK +value: 0x0 +Touch middle of 2nd page: OK +*** C1291T02 PASSED + +*** C1291T03 start ******************************* +** FileMap(2pages) /dev/zero and read +value: 0x0 +Touch head of 1st page: OK +value: 0x0 +Touch middle of 1st page: OK +value: 0x0 +Touch middle of 2nd page: OK +*** C1291T03 PASSED + +*** C1291T04 start ******************************* +mmap01 1 TPASS : Functionality of mmap() successful +*** C1291T04 PASSED (1) + +*** C1291T05 start ******************************* +mmap02 1 TPASS : Functionality of mmap() successful +*** C1291T05 PASSED (1) + +*** C1291T06 start ******************************* +mmap03 1 TPASS : mmap() functionality is correct +*** C1291T06 PASSED (1) + +*** C1291T07 start ******************************* +mmap04 1 TPASS : Functionality of mmap() successful +*** C1291T07 PASSED (1) + +*** C1291T08 start ******************************* +mmap05 1 TPASS : Got SIGSEGV as expected +*** C1291T08 PASSED (1) + +*** C1291T09 start ******************************* +mmap06 1 TPASS : mmap failed with EACCES +*** C1291T09 PASSED (1) + +*** C1291T10 start ******************************* +mmap07 1 TPASS : mmap failed with EACCES +*** C1291T10 PASSED (1) + +*** C1291T11 start ******************************* +mmap08 1 TPASS : mmap failed with EBADF +*** C1291T11 PASSED (1) + +*** C1291T12 start ******************************* +mmap09 1 TPASS : ftruncate mmaped file to a smaller size +mmap09 2 TPASS : ftruncate mmaped file to a larger size +mmap09 3 TPASS : ftruncate mmaped file to 0 size +*** C1291T12 PASSED (3) + +*** C1291T13 start ******************************* +tst_test.c:1096: INFO: Timeout per run is 0h 05m 00s +mmap12.c:103: INFO: All pages are present +mmap12.c:127: PASS: File mapped properly + +Summary: +passed 1 +failed 0 +skipped 0 +warnings 0 +*** C1291T13 PASSED (0) + +*** C1291T14 start ******************************* +mmap14 1 TPASS : Functionality of mmap() successful +*** C1291T14 PASSED (1) + +*** C1291T15 start ******************************* +mmap15 1 TPASS : mmap into high region failed as expected: errno=ENOMEM(12): Cannot allocate memory +*** C1291T15 PASSED (1) +