From 67ebcca74de4d4749ca5b2f2e2b926f4d7ee6982 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Wed, 11 Jul 2018 10:34:12 +0900 Subject: [PATCH] Fix to VMAP virtual address leak Fujitsu: POSTK_DEBUG_TEMP_FIX_51 Refs: #1024 Change-Id: I1692ee4f004cb4d1f725baf47a8ed31fce1bf42a --- arch/arm64/kernel/memory.c | 6 +- arch/x86_64/kernel/memory.c | 6 +- ihk | 2 +- kernel/host.c | 16 ++-- kernel/listeners.c | 2 +- kernel/mem.c | 8 +- kernel/process.c | 3 +- kernel/procfs.c | 4 +- kernel/syscall.c | 2 +- lib/include/ihk/mm.h | 2 +- test/issues/1024/C1024.sh | 74 +++++++++++++++ test/issues/1024/C1024.txt | 147 ++++++++++++++++++++++++++++++ test/issues/1024/C1024T01.c | 171 ++++++++++++++++++++++++++++++++++ test/issues/1024/C1024T02.c | 177 ++++++++++++++++++++++++++++++++++++ test/issues/1024/Makefile | 16 ++++ test/issues/1024/README | 24 +++++ 16 files changed, 631 insertions(+), 29 deletions(-) create mode 100755 test/issues/1024/C1024.sh create mode 100644 test/issues/1024/C1024.txt create mode 100644 test/issues/1024/C1024T01.c create mode 100644 test/issues/1024/C1024T02.c create mode 100644 test/issues/1024/Makefile create mode 100644 test/issues/1024/README diff --git a/arch/arm64/kernel/memory.c b/arch/arm64/kernel/memory.c index bb0fbf0b..cee0ceea 100644 --- a/arch/arm64/kernel/memory.c +++ b/arch/arm64/kernel/memory.c @@ -2934,7 +2934,7 @@ int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t "cpsize: %d\n", __FUNCTION__, to, pa, cpsize); va = ihk_mc_map_virtual(pa, 1, PTATTR_ACTIVE); memcpy(to, va, cpsize); - ihk_mc_unmap_virtual(va, 1, 1); + ihk_mc_unmap_virtual(va, 1); } else { va = phys_to_virt(pa); @@ -3017,7 +3017,7 @@ int write_process_vm(struct process_vm *vm, void *udst, const void *ksrc, size_t "pa: %p, cpsize: %d\n", __FUNCTION__, from, pa, cpsize); va = ihk_mc_map_virtual(pa, 1, PTATTR_WRITABLE|PTATTR_ACTIVE); memcpy(va, from, cpsize); - ihk_mc_unmap_virtual(va, 1, 1); + ihk_mc_unmap_virtual(va, 1); } else { va = phys_to_virt(pa); @@ -3088,7 +3088,7 @@ int patch_process_vm(struct process_vm *vm, void *udst, const void *ksrc, size_t "pa: %p, cpsize: %d\n", __FUNCTION__, from, pa, cpsize); va = ihk_mc_map_virtual(pa, 1, PTATTR_WRITABLE|PTATTR_ACTIVE); memcpy(va, from, cpsize); - ihk_mc_unmap_virtual(va, 1, 1); + ihk_mc_unmap_virtual(va, 1); } else { va = phys_to_virt(pa); diff --git a/arch/x86_64/kernel/memory.c b/arch/x86_64/kernel/memory.c index c7ccee7f..189a9e99 100644 --- a/arch/x86_64/kernel/memory.c +++ b/arch/x86_64/kernel/memory.c @@ -2850,7 +2850,7 @@ int read_process_vm(struct process_vm *vm, void *kdst, const void *usrc, size_t "cpsize: %d\n", __FUNCTION__, to, pa, cpsize); va = ihk_mc_map_virtual(pa, 1, PTATTR_ACTIVE); memcpy(to, va, cpsize); - ihk_mc_unmap_virtual(va, 1, 1); + ihk_mc_unmap_virtual(va, 1); } else { va = phys_to_virt(pa); @@ -2934,7 +2934,7 @@ int write_process_vm(struct process_vm *vm, void *udst, const void *ksrc, size_t "pa: %p, cpsize: %d\n", __FUNCTION__, from, pa, cpsize); va = ihk_mc_map_virtual(pa, 1, PTATTR_ACTIVE); memcpy(va, from, cpsize); - ihk_mc_unmap_virtual(va, 1, 1); + ihk_mc_unmap_virtual(va, 1); } else { va = phys_to_virt(pa); @@ -3005,7 +3005,7 @@ int patch_process_vm(struct process_vm *vm, void *udst, const void *ksrc, size_t "pa: %p, cpsize: %d\n", __FUNCTION__, from, pa, cpsize); va = ihk_mc_map_virtual(pa, 1, PTATTR_ACTIVE); memcpy(va, from, cpsize); - ihk_mc_unmap_virtual(va, 1, 1); + ihk_mc_unmap_virtual(va, 1); } else { va = phys_to_virt(pa); diff --git a/ihk b/ihk index 61e16ef8..3410b5c7 160000 --- a/ihk +++ b/ihk @@ -1 +1 @@ -Subproject commit 61e16ef8bc3665e8414c56fd57b6934023d4a7fa +Subproject commit 3410b5c732b4daab3819868906385710e3c287c4 diff --git a/kernel/host.c b/kernel/host.c index 5d62544e..b1c90da4 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -306,7 +306,7 @@ int prepare_process_ranges_args_envs(struct thread *thread, /* Only unmap remote address if it wasn't specified as an argument */ if (!args) { - ihk_mc_unmap_virtual(args_envs_r, args_envs_npages, 0); + ihk_mc_unmap_virtual(args_envs_r, args_envs_npages); ihk_mc_unmap_memory(NULL, args_envs_rp, p->args_len); } flush_tlb(); @@ -341,7 +341,7 @@ int prepare_process_ranges_args_envs(struct thread *thread, /* Only map remote address if it wasn't specified as an argument */ if (!envs) { - ihk_mc_unmap_virtual(args_envs_r, args_envs_npages, 0); + ihk_mc_unmap_virtual(args_envs_r, args_envs_npages); ihk_mc_unmap_memory(NULL, args_envs_rp, p->envs_len); } flush_tlb(); @@ -449,7 +449,7 @@ static int process_msg_prepare_process(unsigned long rphys) if((pn = kmalloc(sizeof(struct program_load_desc) + sizeof(struct program_image_section) * n, IHK_MC_AP_NOWAIT)) == NULL){ - ihk_mc_unmap_virtual(p, npages, 0); + ihk_mc_unmap_virtual(p, npages); ihk_mc_unmap_memory(NULL, phys, sz); return -ENOMEM; } @@ -460,7 +460,7 @@ static int process_msg_prepare_process(unsigned long rphys) (unsigned long *)&p->cpu_set, sizeof(p->cpu_set))) == NULL) { kfree(pn); - ihk_mc_unmap_virtual(p, npages, 1); + ihk_mc_unmap_virtual(p, npages); ihk_mc_unmap_memory(NULL, phys, sz); return -ENOMEM; } @@ -542,14 +542,14 @@ static int process_msg_prepare_process(unsigned long rphys) kfree(pn); - ihk_mc_unmap_virtual(p, npages, 1); + ihk_mc_unmap_virtual(p, npages); ihk_mc_unmap_memory(NULL, phys, sz); flush_tlb(); return 0; err: kfree(pn); - ihk_mc_unmap_virtual(p, npages, 1); + ihk_mc_unmap_virtual(p, npages); ihk_mc_unmap_memory(NULL, phys, sz); destroy_thread(thread); return -ENOMEM; @@ -653,7 +653,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, pp = ihk_mc_map_memory(NULL, packet->arg, sizeof(struct mcctrl_signal)); sp = (struct mcctrl_signal *)ihk_mc_map_virtual(pp, 1, PTATTR_WRITABLE | PTATTR_ACTIVE); memcpy(&info, sp, sizeof(struct mcctrl_signal)); - ihk_mc_unmap_virtual(sp, 1, 0); + ihk_mc_unmap_virtual(sp, 1); ihk_mc_unmap_memory(NULL, pp, sizeof(struct mcctrl_signal)); pckt.msg = SCD_MSG_SEND_SIGNAL_ACK; pckt.err = 0; @@ -726,7 +726,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, kprintf("%s: SCD_MSG_PERF_CTRL unexpected ctrl_type\n", __FUNCTION__); } - ihk_mc_unmap_virtual(pcd, 1, 0); + ihk_mc_unmap_virtual(pcd, 1); ihk_mc_unmap_memory(NULL, pp, sizeof(struct perf_ctrl_desc)); pckt.msg = SCD_MSG_PERF_ACK; diff --git a/kernel/listeners.c b/kernel/listeners.c index 7dad945a..5dd058e4 100644 --- a/kernel/listeners.c +++ b/kernel/listeners.c @@ -71,7 +71,7 @@ static int test_packet_handler(struct ihk_ikc_channel_desc *c, testmem(v, 4 * 1024 * 1024); - ihk_mc_unmap_virtual(v, 4 * 1024, 1); + ihk_mc_unmap_virtual(v, 4 * 1024); ihk_mc_unmap_memory(NULL, pp, 4 * 1024 * 1024); } else if (packet->msg == 0x11110012) { p.msg = 0x11110013; diff --git a/kernel/mem.c b/kernel/mem.c index 27595637..742dcb49 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -1671,7 +1671,7 @@ void *ihk_mc_map_virtual(unsigned long phys, int npages, return (char *)p + offset; } -void ihk_mc_unmap_virtual(void *va, int npages, int free_physical) +void ihk_mc_unmap_virtual(void *va, int npages) { unsigned long i; @@ -1681,13 +1681,7 @@ void ihk_mc_unmap_virtual(void *va, int npages, int free_physical) flush_tlb_single((unsigned long)(va + (i << PAGE_SHIFT))); } -#ifdef POSTK_DEBUG_TEMP_FIX_51 /* ihk_mc_unmap_virtual() free_physical disabled */ ihk_pagealloc_free(vmap_allocator, (unsigned long)va, npages); -#else /* POSTK_DEBUG_TEMP_FIX_51 */ - if (free_physical) { - ihk_pagealloc_free(vmap_allocator, (unsigned long)va, npages); - } -#endif /* POSTK_DEBUG_TEMP_FIX_51 */ } #ifdef ATTACHED_MIC diff --git a/kernel/process.c b/kernel/process.c index afbeaa06..c193ed85 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1886,7 +1886,6 @@ retry: } else { // Host Kernel memory space const enum ihk_mc_pt_attribute attr = 0; - const int remove_vmap_allocator_entry = 1; void* vmap; vmap = ihk_mc_map_virtual(phys, npages, attr); @@ -1897,7 +1896,7 @@ retry: goto out; } memcpy(virt, vmap, pgsize); - ihk_mc_unmap_virtual(vmap, npages, remove_vmap_allocator_entry); + ihk_mc_unmap_virtual(vmap, npages); } #else /*POSTK_DEBUG_TEMP_FIX_14*/ memcpy(virt, phys_to_virt(phys), pgsize); diff --git a/kernel/procfs.c b/kernel/procfs.c index 071f13f3..c016e164 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -689,7 +689,7 @@ void process_procfs_request(struct ikc_scd_packet *rpacket) kprintf("unsupported procfs entry: %d/%s\n", pid, p); end: - ihk_mc_unmap_virtual(buf, npages, 0); + ihk_mc_unmap_virtual(buf, npages); dprintf("ret: %d, eof: %d\n", ans, eof); r->ret = ans; r->eof = eof; @@ -697,7 +697,7 @@ end: packet.err = 0; bufunavail: ihk_mc_unmap_memory(NULL, pbuf, r->count); - ihk_mc_unmap_virtual(r, 1, 0); + ihk_mc_unmap_virtual(r, 1); dataunavail: ihk_mc_unmap_memory(NULL, parg, sizeof(struct procfs_read)); diff --git a/kernel/syscall.c b/kernel/syscall.c index 1f085629..08bc00c1 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -390,7 +390,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid) requestp = ihk_mc_map_virtual(phys, 1, PTATTR_WRITABLE | PTATTR_ACTIVE); memcpy(&request, requestp, sizeof request); - ihk_mc_unmap_virtual(requestp, 1, 1); + ihk_mc_unmap_virtual(requestp, 1); ihk_mc_unmap_memory(NULL, phys, sizeof(struct syscall_request)); num = request.number; diff --git a/lib/include/ihk/mm.h b/lib/include/ihk/mm.h index f9ff3715..47705489 100644 --- a/lib/include/ihk/mm.h +++ b/lib/include/ihk/mm.h @@ -106,7 +106,7 @@ void ihk_mc_unmap_memory(void *os, unsigned long phys, unsigned long size); void *ihk_mc_map_virtual(unsigned long phys, int npages, enum ihk_mc_pt_attribute attr); -void ihk_mc_unmap_virtual(void *va, int npages, int free_physical); +void ihk_mc_unmap_virtual(void *va, int npages); extern void *sbox_base; extern unsigned int free_bitmap_micpa; diff --git a/test/issues/1024/C1024.sh b/test/issues/1024/C1024.sh new file mode 100755 index 00000000..e3946183 --- /dev/null +++ b/test/issues/1024/C1024.sh @@ -0,0 +1,74 @@ +#!/bin/sh +BIN= +SBIN= +LTP= +BOOTPARAM="-c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1" + +if [ -f ../../../config.h ]; then + str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'` + eval $str +fi +if [ "x$BINDIR" = x ];then + BINDIR="$BIN" +fi + +if [ -f ../../../Makefile ]; then + str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'` + eval $str +fi +if [ "x$SBINDIR" = x ];then + SBINDIR="$SBIN" +fi + +if [ -f $HOME/ltp/testcases/bin/fork01 ]; then + LTPDIR=$HOME/ltp/testcases +fi +if [ "x$LTPDIR" = x ]; then + LTPDIR="$LTP" +fi + +if [ ! -x $SBINDIR/mcreboot.sh ]; then + echo no mcreboot found >&2 + exit 1 +fi +if lsmod | grep mcctrl > /dev/null 2>&1; then + sudo $SBINDIR/mcstop+release.sh + if lsmod | grep mcctrl > /dev/null 2>&1; then + echo shutdown failed >&2 + exit 1 + fi +fi +sudo $SBINDIR/mcreboot.sh $BOOTPARAM +if ! lsmod | grep mcctrl > /dev/null 2>&1; then + echo reboot failed >&2 + exit 1 +fi + +if [ ! -x $BINDIR/mcexec ]; then + echo no mcexec found >&2 + exit 1 +fi + +################################################################################ +rm -f mcexec +ln -s $BINDIR/mcexec +./C1024T01 +./mcexec ./C1024T02 + +if [ x$LTPDIR = x ]; then + echo no LTP found >&2 + exit 1 +fi + +for i in process_vm_readv02:03 process_vm_readv03:04 process_vm_writev02:05; do + tp=`echo $i|sed 's/:.*//'` + id=`echo $i|sed 's/.*://'` + sudo $BINDIR/mcexec $LTPDIR/bin/$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 "*** C1024T$id: $tp OK ($ok)" + else + echo "*** C1024T$id: $tp NG (ok=$ok ng=%ng)" + fi +done diff --git a/test/issues/1024/C1024.txt b/test/issues/1024/C1024.txt new file mode 100644 index 00000000..0233a241 --- /dev/null +++ b/test/issues/1024/C1024.txt @@ -0,0 +1,147 @@ +Script started on Wed Jul 11 19:17:51 2018 +bash-4.2$ make test +gcc -o C1024T01 C1024T01.c -Wall -g +gcc -o C1024T02 C1024T02.c -Wall -g +sh ./C1024.sh +*** C1024T01 START +19:17:54 c=0 +19:22:54 c=9817 +19:27:54 c=18527 +19:32:55 c=27856 +19:37:55 c=37483 +19:42:55 c=45813 +19:47:55 c=55300 +19:52:55 c=64887 +19:57:55 c=73167 +20:02:55 c=82642 +20:07:55 c=92207 +20:12:55 c=100535 +20:17:55 c=109965 +20:22:56 c=119554 +20:27:56 c=127708 +20:32:56 c=137094 +20:37:56 c=146592 +20:42:56 c=154906 +20:47:56 c=164316 +20:52:56 c=173823 +20:57:56 c=181913 +21:02:56 c=191485 +21:07:56 c=201029 +21:12:57 c=209331 +21:17:57 c=218691 +21:22:57 c=228263 +21:27:57 c=236463 +21:32:57 c=245879 +21:37:57 c=255435 +21:42:57 c=263831 +21:47:57 c=273045 +21:52:57 c=282637 +21:57:57 c=290994 +22:02:58 c=300088 +22:07:58 c=309593 +22:12:58 c=318283 +22:17:58 c=327215 +22:22:58 c=336790 +22:27:58 c=345148 +22:32:58 c=354190 +22:37:58 c=363723 +22:42:58 c=372165 +22:47:58 c=381241 +22:52:59 c=390780 +22:57:59 c=399701 +23:02:59 c=408179 +23:07:59 c=417728 +23:12:59 c=426767 +23:17:59 c=435111 +23:22:59 c=444696 +23:27:59 c=454153 +23:32:59 c=462305 +23:37:59 c=471544 +23:43:00 c=481128 +23:48:00 c=489413 +23:53:00 c=498511 +23:58:00 c=508002 +00:03:00 c=516321 +00:08:00 c=525240 +00:13:00 c=534764 +00:18:00 c=543425 +00:23:00 c=552119 +00:28:00 c=561668 +00:33:01 c=570540 +00:38:01 c=578954 +00:43:01 c=588458 +00:48:01 c=597499 +00:53:01 c=605647 +00:58:01 c=615083 +01:03:01 c=624466 +01:08:01 c=632584 +01:13:01 c=641645 +01:18:02 c=651150 +01:23:02 c=659685 +01:28:02 c=668129 +01:33:02 c=677555 +01:38:02 c=686246 +01:43:02 c=694575 +01:48:02 c=704131 +01:53:02 c=713330 +01:58:02 c=721354 +02:03:02 c=730718 +02:08:03 c=740192 +02:13:03 c=748106 +02:18:03 c=757081 +02:23:03 c=766548 +02:28:03 c=775053 +02:33:03 c=783508 +02:38:03 c=793041 +02:43:03 c=802198 +02:48:03 c=810191 +02:53:03 c=819405 +02:58:04 c=828856 +03:03:04 c=836987 +03:08:04 c=845733 +03:13:04 c=855234 +03:18:04 c=863744 +03:23:04 c=872016 +03:28:04 c=881451 +03:33:04 c=890508 +03:38:04 c=898634 +03:43:04 c=907499 +03:48:05 c=916825 +03:53:05 c=924778 +03:58:05 c=933039 +04:03:05 c=942260 +04:08:05 c=950914 +04:13:05 c=958693 +04:18:05 c=967690 +04:23:05 c=976997 +04:28:05 c=984635 +04:33:05 c=993041 +04:38:06 c=1002233 +04:43:06 c=1010732 +04:48:06 c=1018751 +04:53:06 c=1027635 +04:58:06 c=1036889 +05:03:06 c=1044866 +05:05:39 c=1048600 +*** C1024T01 OK +*** C1024T02 START +05:05:42 c=0 +05:06:21 c=1048600 +*** C1024T02 OK +process_vm_readv02 0 TINFO : child 0: memory allocated and initialized. +process_vm_readv02 0 TINFO : child 1: reading string from same memory location. +process_vm_readv02 1 TPASS : expected string received. +*** C1024T03: process_vm_readv02 OK (1) +process_vm_readv03 0 TINFO : child 0: 10 iovecs allocated and initialized. +process_vm_readv03 0 TINFO : child 1: 10 remote iovecs received. +process_vm_readv03 0 TINFO : child 1: 4 local iovecs initialized. +process_vm_readv03 1 TPASS : child 1: all bytes are correctly received. +*** C1024T04: process_vm_readv03 OK (1) +process_vm_writev02 0 TINFO : child 0: memory allocated. +process_vm_writev02 0 TINFO : child 2: write to the same memory location. +process_vm_writev02 1 TPASS : child 0: all bytes are expected. +*** C1024T05: process_vm_writev02 OK (1) +bash-4.2$ exit +exit + +Script done on Thu Jul 12 05:43:43 2018 diff --git a/test/issues/1024/C1024T01.c b/test/issues/1024/C1024T01.c new file mode 100644 index 00000000..a9b6151e --- /dev/null +++ b/test/issues/1024/C1024T01.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EXEC_CNT (1024 * 1024) +#define FORK_CNT 24 + +void +killall() +{ + fprintf(stderr, "*** C1024T01 NG\n"); + fflush(stderr); + kill(-getpid(), SIGKILL); + exit(1); +} + +void +print(int c) +{ + time_t t; + char tbuf[16]; + + time(&t); + strftime(tbuf, 16, "%H:%M:%S", localtime(&t)); + fprintf(stderr, "%s c=%d\n", tbuf, c); + fflush(stderr); +} + +int +main(int argc, char **argv) +{ + int *c; + pid_t pids[FORK_CNT]; + int pfd[FORK_CNT]; + int i; + int st; + int maxfd = -1; + int rc; + char buf[1024]; + + fprintf(stderr, "*** C1024T01 START\n"); + c = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, + -1, 0); + if (c == (void *)-1) { + perror("mmap"); + exit(1); + } + + *c = 0; + print(*c); + setpgid(0, 0); + for (i = 0; i < FORK_CNT; i++) { + int fds[2]; + + if (pipe(fds) == -1) { + perror("pipe"); + exit(1); + } + fflush(stderr); + if ((pids[i] = fork()) == 0) { + close(fds[0]); + close(0); + close(1); + close(2); + open("/dev/null", O_RDONLY); + dup(fds[1]); + dup(fds[1]); + while (*c <= EXEC_CNT) { + pid_t pid; + + if ((pid = fork()) == 0) { + execl("./mcexec", "./mcexec", + "/bin/sleep", "0", NULL); + perror("execve"); + exit(1); + } + if (pid == -1) { + perror("fork"); + exit(1); + } + while ((rc = waitpid(pid, &st, 0)) == -1 && + errno == EINTR); + if (rc == -1) { + perror("wait"); + exit(1); + } + if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { + sprintf(buf, "exit: %08x\n", st); + write(2, buf, strlen(buf)); + exit(1); + } + __sync_fetch_and_add(c, 1); + } + exit(0); + } + close(fds[1]); + pfd[i] = fds[0]; + if (pfd[i] > maxfd) + maxfd = pfd[i]; + if (pids[i] == -1) { + perror("fork"); + killall(); + } + } + for (;;) { + fd_set readfds; + int e = 0; + struct timeval to; + + FD_ZERO(&readfds); + for (i = 0; i < FORK_CNT; i++) { + if (pfd[i] != -1) { + FD_SET(pfd[i], &readfds); + e++; + } + } + if (!e) + break; + to.tv_sec = 300; + to.tv_usec = 0; + rc = select(maxfd + 1, &readfds, NULL, NULL, &to); + if (rc == 0) { + print(*c); + continue; + } + for (i = 0; i < FORK_CNT; i++) { + if (pfd[i] != -1 && FD_ISSET(pfd[i], &readfds)) { + if ((rc = read(pfd[i], buf, 1024)) == -1) { + perror("read"); + killall(); + } + if (rc == 0) { + close(pfd[i]); + pfd[i] = -1; + } + else { + write(2, buf, rc); + killall(); + } + } + } + } + for (i = 0; i < FORK_CNT; i++) { + while ((rc = waitpid(pids[i], &st, 0)) == -1 && errno == EINTR); + if (rc == -1) { + perror("wait"); + killall(); + } + if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { + sprintf(buf, "%d: exit: %08x\n", pids[i], st); + killall(); + } + } + print(*c); + if (*c <= EXEC_CNT) { + fprintf(stderr, "*** C1024T01 NG\n"); + } + + fprintf(stderr, "*** C1024T01 OK\n"); + exit(0); +} diff --git a/test/issues/1024/C1024T02.c b/test/issues/1024/C1024T02.c new file mode 100644 index 00000000..c06cb626 --- /dev/null +++ b/test/issues/1024/C1024T02.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define READ_CNT (1024 *1024) +#define FORK_CNT 24 + +void +killall() +{ + fprintf(stderr, "*** C1024T02 NG\n"); + fflush(stderr); + kill(-getpid(), SIGKILL); + exit(1); +} + +void +print(int c) +{ + time_t t; + char tbuf[16]; + + time(&t); + strftime(tbuf, 16, "%H:%M:%S", localtime(&t)); + fprintf(stderr, "%s c=%d\n", tbuf, c); + fflush(stderr); +} + +int +main(int argc, char **argv) +{ + key_t key; + int shmid; + int *c; + pid_t pids[FORK_CNT]; + int pfd[FORK_CNT]; + int i; + int st; + int maxfd = -1; + int rc; + char buf[1024]; + struct shmid_ds shmbuf; + + fprintf(stderr, "*** C1024T02 START\n"); + key = ftok("C1024T02", 1); + if ((shmid = shmget(key, 4096, IPC_CREAT | 0660)) == -1) { + perror("shmget"); + exit(1); + } + if ((c = shmat(shmid, NULL, 0)) == (void *)-1) { + perror("shmget"); + exit(1); + } + if (shmctl(shmid, IPC_RMID, &shmbuf) == -1) { + perror("RMID"); + exit(1); + } + + *c = 0; + print(*c); + setpgid(0, 0); + for (i = 0; i < FORK_CNT; i++) { + int fds[2]; + + if (pipe(fds) == -1) { + perror("pipe"); + exit(1); + } + fflush(stderr); + if ((pids[i] = fork()) == 0) { + int fd; + + close(fds[0]); + close(0); + close(1); + close(2); + open("/dev/null", O_RDONLY); + dup(fds[1]); + dup(fds[1]); + if ((fd = open("/proc/self/maps", O_RDONLY)) == -1) { + perror("open"); + exit(1); + } + while (*c <= READ_CNT) { + lseek(fd, 0L, SEEK_SET); + if ((rc = read(fd, buf, 1024)) <= 0) { + if (rc == 0) { + fprintf(stderr, "EOF\n"); + } + else { + perror("read"); + } + exit(1); + } + __sync_fetch_and_add(c, 1); + } + exit(0); + } + close(fds[1]); + pfd[i] = fds[0]; + if (pfd[i] > maxfd) + maxfd = pfd[i]; + if (pids[i] == -1) { + perror("fork"); + killall(); + } + } + for (;;) { + fd_set readfds; + int e = 0; + struct timeval to; + + FD_ZERO(&readfds); + for (i = 0; i < FORK_CNT; i++) { + if (pfd[i] != -1) { + FD_SET(pfd[i], &readfds); + e++; + } + } + if (!e) + break; + to.tv_sec = 300; + to.tv_usec = 0; + rc = select(maxfd + 1, &readfds, NULL, NULL, &to); + if (rc == 0) { + print(*c); + continue; + } + for (i = 0; i < FORK_CNT; i++) { + if (pfd[i] != -1 && FD_ISSET(pfd[i], &readfds)) { + if ((rc = read(pfd[i], buf, 1024)) == -1) { + perror("read"); + killall(); + } + if (rc == 0) { + close(pfd[i]); + pfd[i] = -1; + } + else { + write(2, buf, rc); + print(*c); + killall(); + } + } + } + } + for (i = 0; i < FORK_CNT; i++) { + while ((rc = waitpid(pids[i], &st, 0)) == -1 && errno == EINTR); + if (rc == -1) { + perror("wait"); + killall(); + } + if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { + sprintf(buf, "%d: exit: %08x\n", pids[i], st); + killall(); + } + } + print(*c); + if (*c <= READ_CNT) { + fprintf(stderr, "*** C1024T02 NG\n"); + } + + fprintf(stderr, "*** C1024T02 OK\n"); + exit(0); +} diff --git a/test/issues/1024/Makefile b/test/issues/1024/Makefile new file mode 100644 index 00000000..9018b08d --- /dev/null +++ b/test/issues/1024/Makefile @@ -0,0 +1,16 @@ +CC=gcc +TARGET=C1024T01 C1024T02 + +all:: $(TARGET) + +C1024T01: C1024T01.c + $(CC) -o C1024T01 C1024T01.c -Wall -g + +C1024T02: C1024T02.c + $(CC) -o C1024T02 C1024T02.c -Wall -g + +test:: $(TARGET) + sh ./C1024.sh + +clean:: + rm -f *.o $(TARGET) mcexec diff --git a/test/issues/1024/README b/test/issues/1024/README new file mode 100644 index 00000000..da9eafcf --- /dev/null +++ b/test/issues/1024/README @@ -0,0 +1,24 @@ +【Issue#1024 動作確認】 +□ テスト内容 +1. VMAP領域の仮想アドレス回収漏れはプログラム起動時、および、procfsアクセス時 + に存在する。VMAP領域は1M(1024×1024)ページ分の仮想アドレスが割り当て可能 + なので、以下を1M回以上繰り返しても問題が発生しないことを確認する。 +C1024T01 mcexec sleep 0を1M回以上行う +C1024T02 /proc/self/mapsのreadを1M回以上行う + +2. 変更がVMAP領域を使用する他の処理に影響ないことをLTPを用いて確認する。 +C1024T03 process_vm_readv02 (process_vm_readvの処理でVMAPを使用) +C1024T04 process_vm_readv03 (process_vm_readvの処理でVMAPを使用) +C1024T05 process_vm_writev02 (process_vm_writevの処理でVMAPを使用) + +□ 実行手順 +$ make test + +実行できない場合は、C1024.shの以下の行を適切に書き換えた後に実行。 +BIN= mcexec が存在するパス +SBIN= mcreboot.sh が存在するパス +LTP= LTP が存在するパス + +□ 実行結果 +C1024.txt 参照。 +全ての項目が OK となっていることを確認。