diff --git a/fs/exec.c b/fs/exec.c index 263b1f67f1f8..f419a512de63 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1161,6 +1161,20 @@ int begin_new_exec(struct linux_binprm * bprm) if (retval) goto out; + /* + * We have to apply CLOEXEC before we change whether the process is + * dumpable (in setup_new_exec) to avoid a race with a process in userspace + * trying to access the should-be-closed file descriptors of a process + * undergoing exec(2). + * + * This can block on filesystem ->flush() handlers, including waiting + * for FUSE daemons, so do it before exec_mmap takes the + * exec_update_lock. + * This must happen after the point of no return, and after unsharing + * the FD table. + */ + do_close_on_exec(me->files); + /* * Must be called _before_ exec_mmap() as bprm->mm is * not visible until then. Doing it here also ensures @@ -1211,14 +1225,6 @@ int begin_new_exec(struct linux_binprm * bprm) clear_syscall_work_syscall_user_dispatch(me); - /* - * We have to apply CLOEXEC before we change whether the process is - * dumpable (in setup_new_exec) to avoid a race with a process in userspace - * trying to access the should-be-closed file descriptors of a process - * undergoing exec(2). - */ - do_close_on_exec(me->files); - if (bprm->secureexec) { /* Make sure parent cannot signal privileged process. */ me->pdeath_signal = 0;