diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2021-10-08 12:12:56 -0500 |
|---|---|---|
| committer | Eric W. Biederman <ebiederm@xmission.com> | 2021-10-08 12:12:56 -0500 |
| commit | 3f66f86bfed33dee2e9c1d0e14486915bb0750b0 (patch) | |
| tree | 55800c054b48245841afec2f62605d0ef8990dd6 /include/linux | |
| parent | 6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f (diff) | |
| parent | 0258b5fd7c7124b87e185a1a9322d2c66b1876b7 (diff) | |
per signal_struct coredumps
Current coredumps are mixed up with the exit code, the signal handling
code and with the ptrace code in was they are much more complicated than
necessary and difficult to follow.
This series of changes starts with ptrace_stop and cleans it up,
making it easier to follow what is happening in ptrace_stop.
Then cleans up the exec interactions with coredumps.
Then cleans up the coredump interactions with exit.
Then the coredump interactions with the signal handling code is clean
up.
The first and last changes are bug fixes for minor bugs.
I believe the fact that vfork followed by execve can kill the process
the called vfork if exec fails is sufficient justification to change
the userspace visible behavior.
In previous conversations it was suggested that some of these cleanups
did not stand on their own. I think I have managed to organize things
so all of their patches stand on their own.
Which means that if for some reason the last change needs to be reverted
we can still keep the gains from the other changes.
Eric W. Biederman (6):
signal: Remove the bogus sigkill_pending in ptrace_stop
ptrace: Remove the unnecessary arguments from arch_ptrace_stop
exec: Check for a pending fatal signal instead of core_state
exit: Factor coredump_exit_mm out of exit_mm
coredump: Don't perform any cleanups before dumping core
coredump: Limit coredumps to a single thread group
arch/ia64/include/asm/ptrace.h | 4 +-
arch/sparc/include/asm/ptrace.h | 8 ++--
fs/binfmt_elf.c | 4 +-
fs/binfmt_elf_fdpic.c | 2 +-
fs/coredump.c | 88 ++++++-----------------------------------
fs/exec.c | 14 +++----
fs/proc/array.c | 6 +--
include/linux/mm_types.h | 13 ------
include/linux/ptrace.h | 22 +++++------
include/linux/sched.h | 1 +
include/linux/sched/signal.h | 13 ++++++
kernel/exit.c | 76 +++++++++++++++++++----------------
kernel/fork.c | 4 +-
kernel/signal.c | 49 ++++-------------------
mm/debug.c | 4 +-
mm/oom_kill.c | 6 +--
16 files changed, 106 insertions(+), 208 deletions(-)
Link: https://lkml.kernel.org/r/87v92qx2c6.fsf@disp2133
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/mm_types.h | 13 | ||||
| -rw-r--r-- | include/linux/ptrace.h | 22 | ||||
| -rw-r--r-- | include/linux/sched.h | 1 | ||||
| -rw-r--r-- | include/linux/sched/signal.h | 13 |
4 files changed, 23 insertions, 26 deletions
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 7f8ee09c711f..1039f6ae922c 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -387,17 +387,6 @@ struct vm_area_struct { struct vm_userfaultfd_ctx vm_userfaultfd_ctx; } __randomize_layout; -struct core_thread { - struct task_struct *task; - struct core_thread *next; -}; - -struct core_state { - atomic_t nr_threads; - struct core_thread dumper; - struct completion startup; -}; - struct kioctx_table; struct mm_struct { struct { @@ -518,8 +507,6 @@ struct mm_struct { unsigned long flags; /* Must use atomic bitops to access */ - struct core_state *core_state; /* coredumping support */ - #ifdef CONFIG_AIO spinlock_t ioctx_lock; struct kioctx_table __rcu *ioctx_table; diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index b5ebf6c01292..8aee2945ff08 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -362,29 +362,25 @@ static inline void user_single_step_report(struct pt_regs *regs) #ifndef arch_ptrace_stop_needed /** * arch_ptrace_stop_needed - Decide whether arch_ptrace_stop() should be called - * @code: current->exit_code value ptrace will stop with - * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with * * This is called with the siglock held, to decide whether or not it's - * necessary to release the siglock and call arch_ptrace_stop() with the - * same @code and @info arguments. It can be defined to a constant if - * arch_ptrace_stop() is never required, or always is. On machines where - * this makes sense, it should be defined to a quick test to optimize out - * calling arch_ptrace_stop() when it would be superfluous. For example, - * if the thread has not been back to user mode since the last stop, the - * thread state might indicate that nothing needs to be done. + * necessary to release the siglock and call arch_ptrace_stop(). It can be + * defined to a constant if arch_ptrace_stop() is never required, or always + * is. On machines where this makes sense, it should be defined to a quick + * test to optimize out calling arch_ptrace_stop() when it would be + * superfluous. For example, if the thread has not been back to user mode + * since the last stop, the thread state might indicate that nothing needs + * to be done. * * This is guaranteed to be invoked once before a task stops for ptrace and * may include arch-specific operations necessary prior to a ptrace stop. */ -#define arch_ptrace_stop_needed(code, info) (0) +#define arch_ptrace_stop_needed() (0) #endif #ifndef arch_ptrace_stop /** * arch_ptrace_stop - Do machine-specific work before stopping for ptrace - * @code: current->exit_code value ptrace will stop with - * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with * * This is called with no locks held when arch_ptrace_stop_needed() has * just returned nonzero. It is allowed to block, e.g. for user memory @@ -394,7 +390,7 @@ static inline void user_single_step_report(struct pt_regs *regs) * we only do it when the arch requires it for this particular stop, as * indicated by arch_ptrace_stop_needed(). */ -#define arch_ptrace_stop(code, info) do { } while (0) +#define arch_ptrace_stop() do { } while (0) #endif #ifndef current_pt_regs diff --git a/include/linux/sched.h b/include/linux/sched.h index e12b524426b0..f3741f23935e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1664,6 +1664,7 @@ extern struct pid *cad_pid; #define PF_VCPU 0x00000001 /* I'm a virtual CPU */ #define PF_IDLE 0x00000002 /* I am an IDLE thread */ #define PF_EXITING 0x00000004 /* Getting shut down */ +#define PF_POSTCOREDUMP 0x00000008 /* Coredumps should ignore this task */ #define PF_IO_WORKER 0x00000010 /* Task is an IO worker */ #define PF_WQ_WORKER 0x00000020 /* I'm a workqueue worker */ #define PF_FORKNOEXEC 0x00000040 /* Forked but didn't exec */ diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index e5f4ce622ee6..a8fe2a593a3a 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -72,6 +72,17 @@ struct multiprocess_signals { struct hlist_node node; }; +struct core_thread { + struct task_struct *task; + struct core_thread *next; +}; + +struct core_state { + atomic_t nr_threads; + struct core_thread dumper; + struct completion startup; +}; + /* * NOTE! "signal_struct" does not have its own * locking, because a shared signal_struct always @@ -110,6 +121,8 @@ struct signal_struct { int group_stop_count; unsigned int flags; /* see SIGNAL_* flags below */ + struct core_state *core_state; /* coredumping support */ + /* * PR_SET_CHILD_SUBREAPER marks a process, like a service * manager, to re-parent orphan (double-forking) child processes |
