do_syscall: Delegate system calls to the mcexec with the same pid

This includes the following fix:
send_syscall, do_syscall: remove argument pid

Fujitsu: POSTK_TEMP_FIX_26
Refs: #1165
Change-Id: I702362c07a28f507a5e43dd751949aefa24bc8c0
This commit is contained in:
Tomoki Shirasawa
2018-09-07 14:28:23 +09:00
committed by Masamichi Takagi
parent c23bc8d401
commit 7e342751a2
15 changed files with 445 additions and 170 deletions

139
test/issues/1165/C1165.sh Normal file
View File

@@ -0,0 +1,139 @@
#!/bin/sh
BOOTPARAM="-c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1"
USELTP=1
USEOSTEST=1
################################################################################
BINDIR=
SBINDIR=
OSTESTDIR=
LTPDIR=
LTPBIN=
MCEXEC=
TESTMCK=
if [ -f $HOME/mck_test_config ]; then
. $HOME/mck_test_config
elif [ -f ../../../mck_test_config.sample ]; then
. ../../../mck_test_config.sample
else
BIN=
SBIN=
OSTEST=
LTP=
fi
#-------------------------------------------------------------------------------
if [ "x$BIN" = x ]; then
if [ -f ../../../config.h ]; then
str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'`
eval $str
fi
else
BINDIR="$BIN"
fi
if [ "x$SBIN" = x ]; then
if [ -f ../../../Makefile ]; then
str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'`
eval $str
fi
else
SBINDIR="$SBIN"
fi
if [ ! -x "$BINDIR/mcexec" ]; then
echo no mckernel found $BINDIR >&2
exit 1
fi
MCEXEC="$BINDIR/mcexec"
#-------------------------------------------------------------------------------
if [ "x$USELTP" != x ]; then
if [ "x$LTP" = x ]; then
if [ -f "$HOME/ltp/testcases/bin/fork01" ]; then
LTPDIR="$HOME/ltp"
fi
else
LTPDIR="$LTP"
fi
if [ ! -x "$LTPDIR/testcases/bin/fork01" ]; then
echo no LTP found $LTPDIR >&2
exit 1
fi
LTPBIN="$LTPDIR/testcases/bin"
fi
#-------------------------------------------------------------------------------
if [ "x$USEOSTEST" != x ]; then
if [ "x$OSTEST" = x ]; then
if [ -f "$HOME/ostest/bin/test_mck" ]; then
OSTESTDIR="$HOME/ostest"
fi
else
OSTESTDIR="$OSTEST"
fi
if [ ! -x "$OSTESTDIR"/bin/test_mck ]; then
echo no ostest found $OSTESTDIR >&2
exit 1
fi
TESTMCK="$OSTESTDIR/bin/test_mck"
fi
#===============================================================================
if [ ! -x "$SBINDIR/mcstop+release.sh" ]; then
echo mcstop+release: not found >&2
exit 1
fi
echo -n "mcstop+release.sh ... "
sudo "$SBINDIR/mcstop+release.sh"
echo "done"
if lsmod | grep mcctrl > /dev/null 2>&1; then
echo mckernel shutdown failed >&2
exit 1
fi
if [ ! -x "$SBINDIR/mcreboot.sh" ]; then
echo mcreboot: not found >&2
exit 1
fi
echo -n "mcreboot.sh $BOOTPARAM ... "
sudo "$SBINDIR/mcreboot.sh" $BOOTPARAM
echo "done"
if ! lsmod | grep mcctrl > /dev/null 2>&1; then
echo mckernel boot failed >&2
exit 1
fi
################################################################################
$MCEXEC ./C1165T01
sudo sh "$OSTESTDIR"/util/rmmod_test_drv.sh > /dev/null 2>&1
sudo sh "$OSTESTDIR"/util/insmod_test_drv.sh
echo a > mmapfile
sudo timeout -s 9 3 $MCEXEC "$TESTMCK" -s force_exit -n 0 -- -d /dev/test_mck/mmap_dev -f mmapfile
rm -f mmapfile
sudo sh "$OSTESTDIR"/util/rmmod_test_drv.sh
"$SBINDIR"/ihkosctl 0 clear_kmsg
"$SBINDIR"/ihkosctl 0 ioctl 40000000 1
"$SBINDIR"/ihkosctl 0 ioctl 40000000 2
"$SBINDIR"/ihkosctl 0 kmsg | sed 's/[^:]*://' | awk '$2 == "processes" {p = $1} $2 == "threads" {t = $1}END{if (p != 0 || t != 0) {print "*** C1165T02 NG"} else {print "*** C1165T02 OK"}}'
for i in clone01:03 clone03:04 clone04:05 clone06:06 clone07:07 fork01:08 \
fork02:09 fork03:10 fork04:11 fork07:12 fork08:13 fork09:14 \
fork10:15; do
tp=`echo $i|sed 's/:.*//'`
id=`echo $i|sed 's/.*://'`
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 "*** C1165T$id: $tp OK ($ok)"
else
echo "*** C1165T$id: $tp NG (ok=$ok ng=%ng)"
fi
done

View File

@@ -0,0 +1,72 @@
Script started on Tue Aug 28 13:52:33 2018
bash-4.2$ make test
sh ./C1165.sh
mcstop+release.sh ... done
mcreboot.sh -c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1 ... done
*** C1165T01 OK
insmod /home/shirasawa/ostest/util/../bin/test_mck.ko
create charcter device /dev/test_mck/mmap_dev(240:0)
create charcter device /dev/test_mck/mmap_dev2(240:1)
TEST_SUITE: force_exit
TEST_NUMBER: 0
ARGS: -d /dev/test_mck/mmap_dev -f mmapfile
read 1 byte (a(97))
mmap(0x2aaaac73b000)
remove /dev/test_mck
rmmod /home/shirasawa/ostest/util/../bin/test_mck.ko
*** C1165T02 OK
clone01 1 TPASS : clone returned 9933
*** C1165T03: clone01 OK (1)
clone03 1 TPASS : Test passed
*** C1165T04: clone03 OK (1)
clone04 1 TPASS : expected failure; Got EINVAL
*** C1165T05: clone04 OK (1)
clone06 1 TPASS : Test Passed
*** C1165T06: clone06 OK (1)
clone07 1 TPASS : Use of return() in child did not cause SIGSEGV
*** C1165T07: clone07 OK (1)
fork01 1 TPASS : fork() returned 10278
fork01 2 TPASS : child pid and fork() return agree: 10278
*** C1165T08: fork01 OK (2)
fork02 0 TINFO : Inside parent
fork02 0 TINFO : Inside child
fork02 0 TINFO : exit status of wait 0
fork02 1 TPASS : test 1 PASSED
*** C1165T09: fork02 OK (1)
fork03 0 TINFO : process id in parent of child from fork : 10428
fork03 1 TPASS : test 1 PASSED
*** C1165T10: fork03 OK (1)
fork04 1 TPASS : Env var TERM unchanged after fork(): xterm
fork04 2 TPASS : Env var NoTSetzWq unchanged after fork(): getenv() does not find variable set
fork04 3 TPASS : Env var TESTPROG unchanged after fork(): FRKTCS04
*** C1165T11: fork04 OK (3)
fork07 0 TINFO : Forking 100 children
fork07 0 TINFO : Forked all 100 children, now collecting
fork07 0 TINFO : Collected all 100 children
fork07 1 TPASS : 100/100 children read correctly from an inheritted fd
*** C1165T12: fork07 OK (1)
fork08 0 TINFO : parent forksval: 1
fork08 0 TINFO : parent forksval: 2
fork08 0 TINFO : exit status of wait expected 0 got 0
fork08 1 TPASS : parent test PASSED
fork08 0 TINFO : second child got char: b
fork08 1 TPASS : Test passed in childnumber 2
fork08 0 TINFO : exit status of wait expected 0 got 0
fork08 2 TPASS : parent test PASSED
fork08 0 TINFO : exit status of wait expected 0 got 0
fork08 3 TPASS : parent test PASSED
fork08 0 TINFO : Number of processes forked is 2
*** C1165T13: fork08 OK (4)
fork09 0 TINFO : OPEN_MAX is 1024
fork09 0 TINFO : first file descriptor is 12
fork09 0 TINFO : Parent reporting 1023 files open
fork09 0 TINFO : Child opened new file #1023
fork09 1 TPASS : test 1 PASSED
*** C1165T14: fork09 OK (1)
fork10 0 TINFO : fork child A
fork10 1 TPASS : test 1 PASSED
*** C1165T15: fork10 OK (1)
bash-4.2$ exit
exit
Script done on Tue Aug 28 13:53:01 2018

View File

@@ -0,0 +1,97 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
int
main(int argc, char **argv)
{
pid_t pid;
char buf[1024];
int fd;
int rc;
int st;
int i;
fd = open("/dev/zero", O_RDONLY);
if (fd < 0) {
perror("open");
goto err;
}
if ((rc = read(fd, buf, 1024)) != 1024) {
if (rc < 0) {
perror("read");
}
else if (rc == 0) {
fprintf(stderr, "EOF\n");
}
else {
fprintf(stderr, "read too short %d\n", rc);
}
goto err;
}
close(fd);
for (i = 0; i < 1024; i++)
buf[i] = 0x55;
pid = fork();
if (!pid) {
for (i = 0; i < 1024; i++)
if (buf[i] != 0x55) {
exit(2);
}
fd = open("/dev/zero", O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
if ((rc = read(fd, buf, 1024)) != 1024) {
exit(1);
}
close(fd);
for (i = 0; i < 1024; i++)
if (buf[i] != 0) {
exit(3);
}
exit(0);
}
while (waitpid(pid, &st, 0) == -1 && errno == EINTR);
if (!WIFEXITED(st)) {
fprintf(stderr, "child failed %08x\n", st);
goto err;
}
else if (WEXITSTATUS(st) != 0) {
if (WEXITSTATUS(st) == 1) {
fprintf(stderr, "child I/O error\n");
}
else if (WEXITSTATUS(st) == 2) {
fprintf(stderr, "child memory error\n");
}
else if (WEXITSTATUS(st) == 3) {
fprintf(stderr, "child read error\n");
}
else {
fprintf(stderr, "child error %08x\n", st);
}
goto err;
}
for (i = 0; i < 1024; i++)
if (buf[i] != 0x55) {
fprintf(stderr, "BAD value 0x%02x != 0x55\n", buf[i]);
goto err;
}
fprintf(stderr, "*** C1165T01 OK\n");
exit(0);
err:
fprintf(stderr, "*** C1165T01 NG\n");
exit(1);
}

13
test/issues/1165/Makefile Normal file
View File

@@ -0,0 +1,13 @@
CC=gcc
TARGET=C1165T01
all:: $(TARGET)
C1024T01: C1165T01.c
$(CC) -o C1165T01 C1165T01.c -Wall -g
test:: $(TARGET)
sh ./C1165.sh
clean::
rm -f *.o $(TARGET)

53
test/issues/1165/README Normal file
View File

@@ -0,0 +1,53 @@
【Issue#1165 動作確認】
□ テスト内容
Issue#1165 で指摘されている現象は、以下の理由により既に解消されている。
・ kill および gettid のシステムコールデリゲートは、McKernel と同一PIDを持つ
mcexec に対して発行するようになっているため、他プロセスの情報を参照する
ことは無い。
・ 対応する mcexec が終了している状態でシステムコールデリゲートしたとしても、
mcctrl が適切にエラーを返すため、指摘の現象が発生することは無い。
以上を踏まえ、Issue#1165 では、以下の改修を行った。
・ 他 PID の mcexec にシステムコールデリゲートは発生しない (または解消可能)
ので、do_syscall と send_syscall のインタフェースから PID 指定を削除する。
・ 他 PID の mcexec にシステムコールデリゲートする以下の処理は、同一 PID の
mcexec にシステムコールデリゲートするように変更する。
- fork 後、親プロセスから子プロセスの mcexec に PTE の初期化を依頼する処理
このため、Issue#1165に対して以下のテストを行った。
1. fork 後、子プロセスのシステムコールデリゲートで親プロセスの領域が破壊
されないことを確認する。
C1165T01 親プロセスが read 後 fork し、子プロセスが同じアドレスの領域に read
して子プロセスの領域が書き換えられ、親プロセスの領域が書き換えられ
ないことを確認する。
2. 指摘されたプログラムを実行し、残留プロセスが存在しないことを確認する。
C1165T02 ostest force_exit
3. LTP を用いて、変更が既存処理に影響しないことを確認する (以下の LTP が PASS
すること)。
C1165T03 clone01
C1165T04 clone03
C1165T05 clone04
C1165T06 clone06
C1165T07 clone07
C1165T08 fork01
C1165T09 fork02
C1165T10 fork03
C1165T11 fork04
C1165T12 fork07
C1165T13 fork08
C1165T14 fork09
C1165T15 fork10
□ 実行手順
$ make test
実行できない場合は、C1165.shの以下の行を適切に書き換えた後に実行。
BIN= mcexec が存在するパス
SBIN= mcreboot.sh が存在するパス
LTP= LTP が存在するパス
□ 実行結果
C1165.txt 参照。
全ての項目が OK となっていることを確認。