file map: cause SIGBUS when access to a page beyond EOF

Change-Id: Iaf7d792413e674267fd1c05c382212c8f67d8f5b
Refs: #1291
This commit is contained in:
Ken Sato
2019-08-30 13:46:06 +09:00
committed by Masamichi Takagi
parent 1492f16d67
commit c371fbf13b
7 changed files with 341 additions and 1 deletions

View File

@ -43,6 +43,7 @@
#include <linux/semaphore.h>
#include <linux/spinlock.h>
#include <linux/mount.h>
#include <linux/kdev_t.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/io.h>
@ -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) {

62
test/issues/1291/C1291.sh Executable file
View File

@ -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

11
test/issues/1291/Makefile Normal file
View File

@ -0,0 +1,11 @@
CFLAGS=-g
LDFLAGS=
TARGET=map_and_read
all: $(TARGET)
test: all
./C1291.sh
clean:
rm -f $(TARGET) *.o *.txt

41
test/issues/1291/README Normal file
View File

@ -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していることを確認。

View File

@ -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)

View File

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#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);
}

View File

@ -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)