Re: [PATCH 3/3] exec: Allow do_coredump to wait for user space pipe readers to complete (v8)

Neil Horman
2009-07-07T16:19:55Z

Reposting for Oleg to Ack

On Fri, Jul 03, 2009 at 06:52:33AM -0400, Neil Horman wrote:
> core_pattern: Allow core_pattern pipes to wait for user space to complete
>
> One of the things that user space processes like to do is look at metadata for a
> crashing process in their /proc/<pid> directory. this is racy however, since
> do_coredump in the kernel doesn't wait for the user space process to complete
> before it reaps the crashing process. This patch corrects that. Allowing the
> kernel to wait for the user space process to complete before cleaning up the
> crashing process. This is a bit tricky to do for a few reasons:
>
> 1) The user space process isn't our child, so we can't sys_wait4 on it
> 2) We need to close the pipe before waiting for the user process to complete,
> since the user process may rely on an EOF condition
>
> I've discussed several solutions with Oleg Nesterov off-list about this, and
> this is the one we've come up with. We add ourselves as a pipe reader (to
> prevent premature cleanup of the pipe_inode_info), and remove ourselves as a
> writer (to provide an EOF condition to the writer in user space), then we
> iterate until the user space process exits (which we detect by pipe->readers ==
> 1, hence the > 1 check in the loop). When we exit the loop, we restore the
> proper reader/writer values, then we return and let filp_close in do_coredump
> clean up the pipe data properly.
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> Reported-by: Earl Chew <earl_chew@agilent.com>
>
>
> exec.c | 26 ++++++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 93ab6eb..6b3579e 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -55,6 +55,7 @@
> #include <linux/kmod.h>
> #include <linux/fsnotify.h>
> #include <linux/fs_struct.h>
> +#include <linux/pipe_fs_i.h>
>
> #include <asm/uaccess.h>
> #include <asm/mmu_context.h>
> @@ -1711,6 +1712,29 @@ int get_dumpable(struct mm_struct *mm)
> return (ret >= 2) ? 2 : ret;
> }
>
> +static void wait_for_dump_helpers(struct file *file)
> +{
> + struct pipe_inode_info *pipe;
> +
> + pipe = file->f_path.dentry->d_inode->i_pipe;
> +
> + pipe_lock(pipe);
> + pipe->readers++;
> + pipe->writers--;
> +
> + while ((pipe->readers > 1) && (!signal_pending(current))) {
> + wake_up_interruptible_sync(&pipe->wait);
> + kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
> + pipe_wait(pipe);
> + }
> +
> + pipe->readers--;
> + pipe->writers++;
> + pipe_unlock(pipe);
> +
> +}
> +
> +
> void do_coredump(long signr, int exit_code, struct pt_regs *regs)
> {
> struct core_state core_state;
> @@ -1862,6 +1886,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
> current->signal->group_exit_code |= 0x80;
>
> close_fail:
> + if (ispipe && core_pipe_limit)
> + wait_for_dump_helpers(file);
> filp_close(file, NULL);
> fail_dropcount:
> if (dump_count)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>