From: Eric W. Biederman <hidden> Date: 2020-03-08 21:40:23
I have read through the code in exec_mmap and I do not see anything
that depends on sighand or the sighand lock, or on signals in anyway
so this should be safe.
This rearrangement of code has two siginficant benefits. It makes
the determination of passing the point of no return by testing bprm->mm
accurate. All failures prior to that point in flush_old_exec are
either truly recoverable or they are fatal.
Futher this consolidates all of the possible indefinite waits for
userspace together at the top of flush_old_exec. The possible wait
for a ptracer on PTRACE_EVENT_EXIT, the possible wait for a page fault
to be resolved in clear_child_tid, and the possible wait for a page
fault in exit_robust_list.
This consolidation allows the creation of a mutex to replace
cred_guard_mutex that is not held of possible indefinite userspace
waits. Which will allow removing deadlock scenarios from the kernel.
Signed-off-by: "Eric W. Biederman" <redacted>
---
fs/exec.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
I have read through the code in exec_mmap and I do not see anything
that depends on sighand or the sighand lock, or on signals in anyway
so this should be safe.
This rearrangement of code has two siginficant benefits. It makes
^ typo: significant
the determination of passing the point of no return by testing bprm->mm
accurate. All failures prior to that point in flush_old_exec are
either truly recoverable or they are fatal.
Futher this consolidates all of the possible indefinite waits for ^ typo: Further
userspace together at the top of flush_old_exec. The possible wait
for a ptracer on PTRACE_EVENT_EXIT, the possible wait for a page fault
to be resolved in clear_child_tid, and the possible wait for a page
fault in exit_robust_list.
This consolidation allows the creation of a mutex to replace
cred_guard_mutex that is not held of possible indefinite userspace
can you also reword this "held of" thing here as well?
Thanks
Bernd.
On Sun, Mar 08, 2020 at 04:38:00PM -0500, Eric W. Biederman wrote:
I have read through the code in exec_mmap and I do not see anything
that depends on sighand or the sighand lock, or on signals in anyway
so this should be safe.
This rearrangement of code has two siginficant benefits. It makes
the determination of passing the point of no return by testing bprm->mm
accurate. All failures prior to that point in flush_old_exec are
either truly recoverable or they are fatal.
Agreed. Though I see a use of "current", which maybe you want to
parameterize to a "me" argument in acct_arg_size(). (Though looking at
the callers, perhaps there is no benefit?)
quoted hunk
Futher this consolidates all of the possible indefinite waits for
userspace together at the top of flush_old_exec. The possible wait
for a ptracer on PTRACE_EVENT_EXIT, the possible wait for a page fault
to be resolved in clear_child_tid, and the possible wait for a page
fault in exit_robust_list.
This consolidation allows the creation of a mutex to replace
cred_guard_mutex that is not held of possible indefinite userspace
waits. Which will allow removing deadlock scenarios from the kernel.
Signed-off-by: "Eric W. Biederman" <redacted>
---
fs/exec.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
@@ -1272,18 +1272,6 @@ int flush_old_exec(struct linux_binprm * bprm)if(retval)gotoout;-#ifdef CONFIG_POSIX_TIMERS-exit_itimers(me->signal);-flush_itimer_signals();-#endif
I think this comment:
/*
* This is called by do_exit or de_thread, only when there are no more
* references to the shared signal_struct.
*/
void exit_itimers(struct signal_struct *sig)
Refers to there being other threads, yes? Not that the signal table is
private yet?
quoted hunk
-
- /*
- * Make the signal table private.
- */
- retval = unshare_sighand(me);
- if (retval)
- goto out;
-
/*
* Must be called _before_ exec_mmap() as bprm->mm is
* not visibile until then. This also enables the update
I've mostly convinced myself that there are no "side-effects" from having
these timers expire as the mm is going away. I think some kind of comment
of that intent should be explicitly stated here above the timer work.
Beyond that:
Reviewed-by: Kees Cook <redacted>
-Kees
+
+ /*
+ * Make the signal table private.
+ */
+ retval = unshare_sighand(me);
+ if (retval)
+ goto out;
+
set_fs(USER_DS);
me->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD |
PF_NOFREEZE | PF_NO_SETAFFINITY);
--
2.25.0
On Sun, Mar 08, 2020 at 04:38:00PM -0500, Eric W. Biederman wrote:
Futher this consolidates all of the possible indefinite waits for
userspace together at the top of flush_old_exec. The possible wait
for a ptracer on PTRACE_EVENT_EXIT, the possible wait for a page fault
to be resolved in clear_child_tid, and the possible wait for a page
fault in exit_robust_list.
I forgot to mention, just as a point of clarity, there are lots of
other page faults possible, but they're _before_ flush_old_exec()
(i.e. all the copy_strings() calls). Is it worth clarifying this to
"before or at the top of flush_old_exec()" or do you mean something
else? (And as always: perhaps expand flush_old_exec()'s comment to
describe the newly intended state.)
--
Kees Cook