do_fork: If mcexec succeeds for fork and McKernel fails fork, the child process of mcexec will remain.

This commit is contained in:
Tomoki Shirasawa
2018-02-14 16:37:38 +09:00
parent 840acd6021
commit c9157f273f
2 changed files with 75 additions and 64 deletions

View File

@ -233,12 +233,13 @@ static int nr_processes = 0;
static int nr_threads = -1;
struct fork_sync {
pid_t pid;
int status;
volatile int success;
sem_t sem;
};
struct fork_sync_container {
pid_t pid;
struct fork_sync_container *next;
struct fork_sync *fs;
};
@ -3398,68 +3399,56 @@ gettid_out:
case __NR_clone: {
struct fork_sync *fs;
struct fork_sync_container *fsc;
struct fork_sync_container *fsc = NULL;
struct fork_sync_container *fp;
struct fork_sync_container *fb;
int flag = w.sr.args[0];
int rc = -1;
pid_t pid;
if (flag == 1) {
pid = w.sr.args[1];
rc = 0;
pthread_mutex_lock(&fork_sync_mutex);
for (fp = fork_sync_top, fb = NULL; fp; fb = fp, fp = fp->next)
if (fp->pid == pid)
break;
if (fp) {
fs = fp->fs;
if (fb)
fb->next = fp->next;
else
fork_sync_top = fp->next;
fs->success = 1;
munmap(fs, sizeof(struct fork_sync));
free(fp);
}
pthread_mutex_unlock(&fork_sync_mutex);
do_syscall_return(fd, cpu, rc, 0, 0, 0, 0);
break;
}
fs = mmap(NULL, sizeof(struct fork_sync),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (fs == (void *)-1) {
goto fork_err;
}
memset(fs, '\0', sizeof(struct fork_sync));
sem_init(&fs->sem, 1, 0);
fsc = malloc(sizeof(struct fork_sync_container));
if (!fsc) {
goto fork_err;
}
memset(fsc, '\0', sizeof(struct fork_sync_container));
pthread_mutex_lock(&fork_sync_mutex);
fsc->next = fork_sync_top;
fork_sync_top = fsc;
pthread_mutex_unlock(&fork_sync_mutex);
fsc->fs = fs = mmap(NULL, sizeof(struct fork_sync),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if(fs == (void *)-1){
goto fork_err;
}
fsc->fs = fs;
memset(fs, '\0', sizeof(struct fork_sync));
sem_init(&fs->sem, 1, 0);
if(flag){
int pipefds[2];
if(pipe(pipefds) == -1){
rc = -errno;
sem_destroy(&fs->sem);
goto fork_err;
}
pid = fork();
if(pid == 0){
close(pipefds[0]);
pid = fork();
if(pid != 0){
if (write(pipefds[1], &pid, sizeof pid) != sizeof(pid)) {
fprintf(stderr, "error: writing pipefds\n");
}
exit(0);
}
}
else if(pid != -1){
int npid;
int st;
close(pipefds[1]);
if (read(pipefds[0], &npid, sizeof npid) != sizeof(npid)) {
fprintf(stderr, "error: reading pipefds\n");
}
close(pipefds[0]);
waitpid(pid, &st, 0);
pid = npid;
}
else{
rc = -errno;
sem_destroy(&fs->sem);
goto fork_err;
}
}
else
pid = fork();
fsc->pid = pid = fork();
switch (pid) {
/* Error */
@ -3525,12 +3514,13 @@ gettid_out:
fork_child_sync_pipe:
sem_post(&fs->sem);
sem_destroy(&fs->sem);
if (fs->status)
exit(1);
for (fp = fork_sync_top; fp;) {
fb = fp->next;
if (fp->fs)
if (fp->fs && fp->fs != fs)
munmap(fp->fs, sizeof(struct fork_sync));
free(fp);
fp = fb;
@ -3542,6 +3532,16 @@ fork_child_sync_pipe:
ioctl(fd, MCEXEC_UP_NEW_PROCESS, &npdesc);
/* TODO: does the forked thread run in a pthread context? */
while (getppid() != 1 &&
fs->success == 0) {
sched_yield();
}
if (fs->success == 0) {
exit(1);
}
munmap(fs, sizeof(struct fork_sync));
join_all_threads();
return ret;
@ -3549,7 +3549,6 @@ fork_child_sync_pipe:
/* Parent */
default:
fs->pid = pid;
while ((rc = sem_trywait(&fs->sem)) == -1 && (errno == EAGAIN || errno == EINTR)) {
int st;
int wrc;
@ -3572,20 +3571,25 @@ fork_child_sync_pipe:
break;
}
sem_destroy(&fs->sem);
munmap(fs, sizeof(struct fork_sync));
fork_err:
pthread_mutex_lock(&fork_sync_mutex);
for (fp = fork_sync_top, fb = NULL; fp; fb = fp, fp = fp->next)
if (fp == fsc)
break;
if (fp) {
if (fb)
fb->next = fsc->next;
else
fork_sync_top = fsc->next;
if (fs) {
sem_destroy(&fs->sem);
if (rc < 0) {
munmap(fs, sizeof(struct fork_sync));
pthread_mutex_lock(&fork_sync_mutex);
for (fp = fork_sync_top, fb = NULL; fp; fb = fp, fp = fp->next)
if (fp == fsc)
break;
if (fp) {
if (fb)
fb->next = fsc->next;
else
fork_sync_top = fsc->next;
free(fp);
}
pthread_mutex_unlock(&fork_sync_mutex);
}
}
pthread_mutex_unlock(&fork_sync_mutex);
do_syscall_return(fd, cpu, rc, 0, 0, 0, 0);
break;
}

View File

@ -2615,6 +2615,13 @@ retry_tid:
old->tid,
new->tid);
if (!(clone_flags & CLONE_VM)) {
request1.number = __NR_clone;
request1.args[0] = 1;
request1.args[1] = new->tid;
do_syscall(&request1, ihk_mc_get_processor_id(), 0);
}
runq_add_thread(new, cpuid);
if (ptrace_event) {