Partial revert of 8280d16172243702ed43432f826ca6130edb4086 From: Pavel Roskin This prevents hanging login on Fedora 16: [ 241.482118] INFO: task gnome-settings-:3155 blocked for more than 120 seconds. [ 241.483499] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 241.484888] gnome-settings- D 0000000000000000 6136 3155 1 0x00000000 [ 241.486265] ffff8801298afcc8 0000000000000046 ffff88012993b420 0000000000000246 [ 241.487652] ffff8801298affd8 ffff8801298affd8 ffff8801298affd8 ffff8801298affd8 [ 241.489035] ffff88012993a2c0 ffff88012993b420 ffff880128cb0b80 ffff88012993b420 [ 241.490421] Call Trace: [ 241.491765] [] schedule+0x24/0x70 [ 241.493116] [] exit_mm+0x85/0x120 [ 241.494467] [] do_exit+0x13f/0x580 [ 241.495784] [] do_group_exit+0x47/0xb0 [ 241.497090] [] get_signal_to_deliver+0x21f/0x580 [ 241.498384] [] do_signal+0x24/0x120 [ 241.499673] [] ? sysret_signal+0x5/0x47 [ 241.500964] [] do_notify_resume+0x65/0xa0 [ 241.502239] [] ? trace_hardirqs_on_thunk+0x3a/0x3f [ 241.503525] [] int_signal+0x12/0x17 [ 241.504813] no locks held by gnome-settings-/3155. --- fs/coredump.c | 21 ++++++++++++++++++++- 1 files changed, 20 insertions(+), 1 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index fd37fac..1d5e301 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -429,6 +429,16 @@ static void wait_for_dump_helpers(struct file *file) } +static inline void __clear_close_on_exec(int fd, struct fdtable *fdt) +{ + __clear_bit(fd, fdt->close_on_exec); +} + +static inline void __set_open_fd(int fd, struct fdtable *fdt) +{ + __set_bit(fd, fdt->open_fds); +} + /* * umh_pipe_setup * helper function to customize the process used @@ -443,14 +453,23 @@ static void wait_for_dump_helpers(struct file *file) static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) { struct file *files[2]; + struct fdtable *fdt; struct coredump_params *cp = (struct coredump_params *)info->data; + struct files_struct *cf = current->files; int err = create_pipe_files(files, 0); if (err) return err; cp->file = files[1]; - replace_fd(0, files[0], 0); + sys_close(0); + fd_install(0, files[0]); + spin_lock(&cf->file_lock); + fdt = files_fdtable(cf); + __set_open_fd(0, fdt); + __clear_close_on_exec(0, fdt); + spin_unlock(&cf->file_lock); + /* and disallow core files too */ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};