| @@ -119,37 +119,16 @@ static void call_usermodehelper_exec_sync(struct subprocess_info *sub_info) · 118 unmodified lines |
| 119 | 119 | { |
| 120 | 120 | pid_t pid; |
| 121 | 121 | |
| 122 | | − /* If SIGCLD is ignored kernel_wait4 won't populate the status. */ |
| 122 | + /* If SIGCLD is ignored do_wait won't populate the status. */ |
| 123 | 123 | kernel_sigaction(SIGCHLD, SIG_DFL); |
| 124 | 124 | pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD); |
| 125 | | − if (pid < 0) { |
| 125 | + if (pid < 0) |
| 126 | 126 | sub_info->retval = pid; |
| 127 | | − } else { |
| 128 | | − int ret = -ECHILD; |
| 129 | | − /* |
| 130 | | − * Normally it is bogus to call wait4() from in-kernel because |
| 131 | | − * wait4() wants to write the exit code to a userspace address. |
| 132 | | − * But call_usermodehelper_exec_sync() always runs as kernel |
| 133 | | − * thread (workqueue) and put_user() to a kernel address works |
| 134 | | − * OK for kernel threads, due to their having an mm_segment_t |
| 135 | | − * which spans the entire address space. |
| 136 | | − * |
| 137 | | − * Thus the __user pointer cast is valid here. |
| 138 | | − */ |
| 139 | | − kernel_wait4(pid, (int __user *)&ret, 0, NULL); |
| 140 | | − |
| 141 | | − /* |
| 142 | | − * If ret is 0, either call_usermodehelper_exec_async failed and |
| 143 | | − * the real error code is already in sub_info->retval or |
| 144 | | − * sub_info->retval is 0 anyway, so don't mess with it then. |
| 145 | | − */ |
| 146 | | − if (ret) |
| 147 | | − sub_info->retval = ret; |
| 148 | | − } |
| 127 | + else |
| 128 | + kernel_wait(pid, &sub_info->retval); |
| 149 | 129 | |
| 150 | 130 | /* Restore default kernel sig handler */ |
| 151 | 131 | kernel_sigaction(SIGCHLD, SIG_IGN); |
| 152 | | − |
| 153 | 132 | umh_complete(sub_info); |
| 154 | 133 | } |
| 155 | 134 | |