procfs: Fix pread/pwrite to procfs fail when specified size is bigger than 4MB

Fujitsu: POSTK_DEBUG_TEMP_FIX_43
Refs: #1018
Change-Id: I736ac69885695ef8eeababc3fcfe69a6258b4e16
This commit is contained in:
Ken Sato
2018-08-08 17:00:28 +09:00
committed by Masamichi Takagi
parent ab284b0531
commit dd58d366c3
8 changed files with 410 additions and 164 deletions

79
test/issues/1018/C1018.sh Normal file
View File

@@ -0,0 +1,79 @@
#!/bin/sh
if [ -f $HOME/mck_test_config ]; then
. $HOME/mck_test_config
else
BIN=
SBIN=
OSTEST=
fi
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 10G@0,10G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
if [ "x$BINDIR" = x ];then
BINDIR="$BIN"
fi
if [ "x$SBINDIR" = x ];then
SBINDIR="$SBIN"
fi
if [ "x$OSTESTDIR" = x ]; then
OSTESTDIR="$OSTEST"
fi
if [ "x$LTPDIR" = x ]; then
LTPDIR="$LTP"
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 [ ! -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 [ ! -x $BINDIR/mcexec ]; then
echo mcexec: not found >&2
exit 1
fi
$BINDIR/mcexec ./CT_001
$BINDIR/mcexec ./CT_002
tid=001
echo "*** RT_$tid start *******************************"
sudo $BINDIR/mcexec $OSTESTDIR/bin/test_mck -s procfs -n 0 2>&1 | tee ./RT_${tid}.txt
if grep -v "RESULT: TP failed" ./RT_${tid}.txt > /dev/null 2>&1 ; then
echo "*** RT_$tid: PASSED"
else
echo "*** RT_$tid: FAILED"
fi
echo ""
tid=002
echo "*** RT_$tid start *******************************"
sudo $BINDIR/mcexec $OSTESTDIR/bin/test_mck -s procfs -n 1 2>&1 | tee ./RT_${tid}.txt
if grep -v "RESULT: TP failed" ./RT_${tid}.txt > /dev/null 2>&1 ; then
echo "*** RT_$tid: PASSED"
else
echo "*** RT_$tid: FAILED"
fi
echo ""
tid=003
echo "*** RT_$tid start *******************************"
sudo $BINDIR/mcexec $OSTESTDIR/bin/test_mck -s procfs -n 3 2>&1 | tee ./RT_${tid}.txt
if grep -v "RESULT: TP failed" ./RT_${tid}.txt > /dev/null 2>&1 ; then
echo "*** RT_$tid: PASSED"
else
echo "*** RT_$tid: FAILED"
fi
echo ""

99
test/issues/1018/CT_001.c Normal file
View File

@@ -0,0 +1,99 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "./test_chk.h"
#define TEST_NAME "CT_001"
#define MEGA (1024 * 1024)
#define PROCFILE_LEN 128
#define MAP_LEN (8 * MEGA)
int main(int argc, char *argv[])
{
int fd = 0, i = 0;
pid_t pid = getpid();
char pfname[PROCFILE_LEN];
unsigned long *anon_map = NULL;
unsigned long *tmp_buf = NULL;
int data_pos[3] = {1 * MEGA / sizeof(unsigned long),
2 * MEGA / sizeof(unsigned long),
4 * MEGA / sizeof(unsigned long)};
off_t ret = 0;
printf("*** %s start *******************************\n", TEST_NAME);
/* anonymous mmap */
anon_map = (unsigned long *)mmap(NULL, MAP_LEN, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
OKNG(anon_map == MAP_FAILED, "mmap device file");
printf(" anonymous map to %p, size:%.2f MB\n",
anon_map, (double)MAP_LEN / MEGA);
/* allocate tmp_buf */
tmp_buf = (unsigned long *)mmap(NULL, MAP_LEN, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
CHKANDJUMP(tmp_buf == NULL, "alloc tmp_buf");
/* set magic_number */
anon_map[data_pos[0]] = 0x1111;
anon_map[data_pos[1]] = 0x2222;
anon_map[data_pos[2]] = 0x3333;
/* generate proc_mem path */
sprintf(pfname, "/proc/%d/mem", pid);
/* open proc_mem */
fd = open(pfname, O_RDWR);
CHKANDJUMP(fd < 0, "open proc_mem");
/* pread 2MB */
errno = 0;
ret = pread(fd, tmp_buf, 2 * MEGA, (off_t)anon_map);
OKNG(ret != 2 * MEGA || errno != 0, "2MB pread");
/* check read data */
OKNG(tmp_buf[data_pos[0]] != anon_map[data_pos[0]],
"check read data :0x%lx", tmp_buf[data_pos[0]]);
/* pread 4MB */
errno = 0;
ret = pread(fd, tmp_buf, 4 * MEGA, (off_t)anon_map);
OKNG(ret != 4 * MEGA || errno != 0, "4MB pread");
/* check read data */
OKNG(tmp_buf[data_pos[1]] != anon_map[data_pos[1]],
"check read data :0x%lx", tmp_buf[data_pos[1]]);
/* pread 8MB */
errno = 0;
ret = pread(fd, tmp_buf, 8 * MEGA, (off_t)anon_map);
OKNG(ret != 8 * MEGA || errno != 0, "8MB pread");
/* check read data */
OKNG(tmp_buf[data_pos[2]] != anon_map[data_pos[2]],
"check read data :0x%lx", tmp_buf[data_pos[2]]);
close(fd);
printf("*** %s PASSED\n\n", TEST_NAME);
return 0;
fn_fail:
if (fd > 0) {
close(fd);
}
printf("*** %s FAILED\n\n", TEST_NAME);
return -1;
}

89
test/issues/1018/CT_002.c Normal file
View File

@@ -0,0 +1,89 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "./test_chk.h"
#define TEST_NAME "CT_002"
#define MEGA (1024 * 1024)
#define PROCFILE_LEN 128
#define MAP_LEN (8 * MEGA)
int main(int argc, char *argv[])
{
int fd = 0, i = 0;
pid_t pid = getpid();
char pfname[PROCFILE_LEN];
unsigned long *anon_map = NULL;
unsigned long *tmp_buf = NULL;
int data_pos[3] = {0 * MEGA / sizeof(unsigned long),
1 * MEGA / sizeof(unsigned long),
4 * MEGA / sizeof(unsigned long)};
off_t ret = 0;
printf("*** %s start *******************************\n", TEST_NAME);
/* anonymous mmap */
anon_map = (unsigned long *)mmap(NULL, MAP_LEN, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
OKNG(anon_map == MAP_FAILED, "anonymous map");
printf(" anonymous map to %p, size:%.2f MB\n",
anon_map, (double)MAP_LEN / MEGA);
/* allocate tmp_buf */
tmp_buf = (unsigned long *)mmap(NULL, MAP_LEN, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
CHKANDJUMP(tmp_buf == MAP_FAILED, "alloc tmp_buf");
/* set magic_number */
tmp_buf[data_pos[0]] = 0x1111;
tmp_buf[data_pos[1]] = 0x2222;
tmp_buf[data_pos[2]] = 0x3333;
/* generate proc_mem path */
sprintf(pfname, "/proc/%d/mem", pid);
/* open proc_mem */
fd = open(pfname, O_RDWR);
CHKANDJUMP(fd < 0, "open proc_mem");
/* pwrite 2MB */
errno = 0;
ret = pwrite(fd, tmp_buf, 2 * MEGA, (off_t)anon_map);
OKNG(ret != 2 * MEGA || errno != 0, "2MB pwrite");
/* pwrite 4MB */
errno = 0;
ret = pwrite(fd, tmp_buf, 4 * MEGA, (off_t)anon_map);
OKNG(ret != 4 * MEGA || errno != 0, "4MB pwrite");
/* pwrite 8MB */
errno = 0;
ret = pwrite(fd, tmp_buf, 8 * MEGA, (off_t)anon_map);
OKNG(ret != 8 * MEGA || errno != 0, "8MB pwrite");
close(fd);
printf("*** %s PASSED\n\n", TEST_NAME);
return 0;
fn_fail:
if (fd > 0) {
close(fd);
}
printf("*** %s FAILED\n\n", TEST_NAME);
return -1;
}

20
test/issues/1018/Makefile Normal file
View File

@@ -0,0 +1,20 @@
CC = gcc
TARGET=CT_001 CT_002
CPPFLAGS =
LDFLAGS =
all: $(TARGET)
CT_001: CT_001.c
$(CC) -o $@ $^ $(LDFLAGS)
CT_002: CT_002.c
$(CC) -o $@ $^ $(LDFLAGS)
test: all
@sh ./C1018.sh
clean:
rm -f $(TARGET) *.o

38
test/issues/1018/README Normal file
View File

@@ -0,0 +1,38 @@
【Issue#1018 動作確認】
□ テスト内容
1. Issueで報告された再現プログラムでの確認
CT_001: /proc/<PID>/mem に対するpread
/proc/<PID>/mem に対して、2MB, 4MB, 8MB でそれぞれpreadを実行し、
preadが成功することと、読み取ったデータが正しいことを確認
CT_002: /proc/<PID>/mem に対するpwrite
/proc/<PID>/mem に対して、2MB, 4MB, 8MB でそれぞれpwriteを実行し、
pwriteが成功することを確認
2. 既存のprocfs機能に影響がないことをOSTESTを用いて確認
RT_001: ostest_procfs.000
/proc/<PID>/auxv の内容を取得できることを確認
RT_002: ostest_procfs.001
/proc/<PID>/mem の内容を取得できることを確認
RT_003: ostest_procfs.003
/proc/<PID>/stat の内容を取得できることを確認
□ 実行手順
McKernelのインストール先や、OSTEST, LTPの配置場所は、
$HOME/mck_test_config を参照している
mck_test_config は、McKernelをビルドした際に生成される
mck_test_config.sample ファイルを$HOMEにコピーし、適宜編集する
$ make test
実行できない場合は、C1018.shの以下の行を適切に書き換えた後に実行。
BIN= mcexec が存在するパス
SBIN= mcreboot.sh が存在するパス
OSTEST= OSTESTが存在するパス
LTP= LTPが存在するパス
□ 実行結果
result.log 参照。
すべての項目をPASSしていることを確認。

View File

@@ -0,0 +1,62 @@
*** CT_001 start *******************************
[OK] mmap device file
anonymous map to 0x2aaaab200000, size:8.00 MB
[OK] 2MB pread
[OK] check read data :0x1111
[OK] 4MB pread
[OK] check read data :0x2222
[OK] 8MB pread
[OK] check read data :0x3333
*** CT_001 PASSED
*** CT_002 start *******************************
[OK] anonymous map
anonymous map to 0x2aaaab200000, size:8.00 MB
[OK] 2MB pwrite
[OK] 4MB pwrite
[OK] 8MB pwrite
*** CT_002 PASSED
*** RT_001 start *******************************
TEST_SUITE: procfs
TEST_NUMBER: 0
ARGS:
dump /proc/5267/auxv:
0x00000000000021 0x002aaaaac24000 (AT_SYSINFO_EHDR)
0x00000000000019 0x00547fffffffe0 (AT_RANDOM)
0x00000000000011 0x00000000000064 (AT_CLKTCK)
0x00000000000006 0x00000000001000 (AT_PAGESZ)
0x00000000000003 0x00000000400040 (AT_PHDR)
0x00000000000004 0x00000000000038 (AT_PHENT)
0x00000000000005 0x0000000000000a (AT_PHNUM)
0x00000000000009 0x00000000403430 (AT_ENTRY)
0000000000000000 0000000000000000 (AT_NULL)
RESULT: you need check AUXV value
*** RT_001: PASSED
*** RT_002 start *******************************
TEST_SUITE: procfs
TEST_NUMBER: 1
ARGS:
allocated: 0x00000000800010
dump /proc/5301/mem(offset:0x00000000800010):
0x00000000800010: 0000000000000000 0000000000000001 0000000000000002 0000000000000003
0x00000000800030: 0000000000000004 0000000000000005 0000000000000006 0000000000000007
0x00000000800050: 0000000000000008 0000000000000009 000000000000000a 000000000000000b
0x00000000800070: 000000000000000c 000000000000000d 000000000000000e 000000000000000f
0x00000000800090: 0000000000000010 0000000000000011 0000000000000012 0000000000000013
0x000000008000b0: 0000000000000014 0000000000000015 0000000000000016 0000000000000017
0x000000008000d0: 0000000000000018 0000000000000019 000000000000001a 000000000000001b
0x000000008000f0: 000000000000001c 000000000000001d 000000000000001e 000000000000001f
RESULT: you need check MEM value
*** RT_002: PASSED
*** RT_003 start *******************************
TEST_SUITE: procfs
TEST_NUMBER: 3
ARGS:
output /proc/5335/task/5366/stat
0 (exe) R 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
RESULT: you need check STAT value
*** RT_003: PASSED

View File

@@ -0,0 +1,23 @@
#ifndef HEADER_TEST_CHK_H
#define HEADER_TEST_CHK_H
#define CHKANDJUMP(cond, ...) do {\
if (cond) {\
fprintf(stderr, " [NG] ");\
fprintf(stderr, __VA_ARGS__);\
fprintf(stderr, " failed\n");\
goto fn_fail;\
} \
} while (0)
#define OKNG(cond, ...) do {\
if (cond) {\
CHKANDJUMP(cond, __VA_ARGS__);\
} else {\
fprintf(stdout, " [OK] ");\
fprintf(stdout, __VA_ARGS__);\
fprintf(stdout, "\n");\
} \
} while (0)
#endif