Commit 6b7aaad9 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: Fix handling of failed execs of helpers

There were some bugs in handling failures to exec helper programs.  errno was
passed back from the child with the wrong sign.  It was also ignored.  In the
case where it mattered, the errno from the (successful) read in the parent was
used instead.
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5e1f65a6
...@@ -42,7 +42,7 @@ static int helper_child(void *arg) ...@@ -42,7 +42,7 @@ static int helper_child(void *arg)
if(data->pre_exec != NULL) if(data->pre_exec != NULL)
(*data->pre_exec)(data->pre_data); (*data->pre_exec)(data->pre_data);
execvp(argv[0], argv); execvp(argv[0], argv);
errval = errno; errval = -errno;
printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
os_write_file(data->fd, &errval, sizeof(errval)); os_write_file(data->fd, &errval, sizeof(errval));
kill(os_getpid(), SIGKILL); kill(os_getpid(), SIGKILL);
...@@ -62,7 +62,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, ...@@ -62,7 +62,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
stack = *stack_out; stack = *stack_out;
else stack = alloc_stack(0, __cant_sleep()); else stack = alloc_stack(0, __cant_sleep());
if(stack == 0) if(stack == 0)
return(-ENOMEM); return -ENOMEM;
ret = os_pipe(fds, 1, 0); ret = os_pipe(fds, 1, 0);
if(ret < 0){ if(ret < 0){
...@@ -95,16 +95,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, ...@@ -95,16 +95,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
/* Read the errno value from the child, if the exec failed, or get 0 if /* Read the errno value from the child, if the exec failed, or get 0 if
* the exec succeeded because the pipe fd was set as close-on-exec. */ * the exec succeeded because the pipe fd was set as close-on-exec. */
n = os_read_file(fds[0], &ret, sizeof(ret)); n = os_read_file(fds[0], &ret, sizeof(ret));
if (n < 0) { if(n == 0)
printk("run_helper : read on pipe failed, ret = %d\n", -n); ret = pid;
else {
if(n < 0){
printk("run_helper : read on pipe failed, ret = %d\n",
-n);
ret = n; ret = n;
kill(pid, SIGKILL); kill(pid, SIGKILL);
}
CATCH_EINTR(waitpid(pid, NULL, 0)); CATCH_EINTR(waitpid(pid, NULL, 0));
} else if(n != 0){
CATCH_EINTR(n = waitpid(pid, NULL, 0));
ret = -errno;
} else {
ret = pid;
} }
out_close: out_close:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment