exit: Add and use make_task_dead.
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 24 Jan 2023 18:50:56 +0000 (10:50 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Feb 2023 07:27:20 +0000 (08:27 +0100)
commit 0e25498f8cd43c1b5aa327f373dd094e9a006da7 upstream.

There are two big uses of do_exit.  The first is it's design use to be
the guts of the exit(2) system call.  The second use is to terminate
a task after something catastrophic has happened like a NULL pointer
in kernel code.

Add a function make_task_dead that is initialy exactly the same as
do_exit to cover the cases where do_exit is called to handle
catastrophic failure.  In time this can probably be reduced to just a
light wrapper around do_task_dead. For now keep it exactly the same so
that there will be no behavioral differences introducing this new
concept.

Replace all of the uses of do_exit that use it for catastraphic
task cleanup with make_task_dead to make it clear what the code
is doing.

As part of this rename rewind_stack_do_exit
rewind_stack_and_make_dead.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
39 files changed:
arch/alpha/kernel/traps.c
arch/alpha/mm/fault.c
arch/arm/kernel/traps.c
arch/arm/mm/fault.c
arch/arm64/kernel/traps.c
arch/arm64/mm/fault.c
arch/csky/abiv1/alignment.c
arch/csky/kernel/traps.c
arch/csky/mm/fault.c
arch/h8300/kernel/traps.c
arch/h8300/mm/fault.c
arch/hexagon/kernel/traps.c
arch/ia64/kernel/mca_drv.c
arch/ia64/kernel/traps.c
arch/ia64/mm/fault.c
arch/m68k/kernel/traps.c
arch/m68k/mm/fault.c
arch/microblaze/kernel/exceptions.c
arch/mips/kernel/traps.c
arch/nds32/kernel/fpu.c
arch/nds32/kernel/traps.c
arch/nios2/kernel/traps.c
arch/openrisc/kernel/traps.c
arch/parisc/kernel/traps.c
arch/powerpc/kernel/traps.c
arch/riscv/kernel/traps.c
arch/riscv/mm/fault.c
arch/s390/kernel/dumpstack.c
arch/s390/kernel/nmi.c
arch/sh/kernel/traps.c
arch/sparc/kernel/traps_32.c
arch/sparc/kernel/traps_64.c
arch/x86/entry/entry_32.S
arch/x86/entry/entry_64.S
arch/x86/kernel/dumpstack.c
arch/xtensa/kernel/traps.c
include/linux/sched/task.h
kernel/exit.c
tools/objtool/check.c

index e805106..f5ba12a 100644 (file)
@@ -192,7 +192,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
                local_irq_enable();
                while (1);
        }
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
 
 #ifndef CONFIG_MATHEMU
@@ -577,7 +577,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
 
        printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
                pc, va, opcode, reg);
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 
 got_exception:
        /* Ok, we caught the exception, but we don't want it.  Is there
@@ -632,7 +632,7 @@ got_exception:
                local_irq_enable();
                while (1);
        }
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
 
 /*
index eee5102..e9193d5 100644 (file)
@@ -204,7 +204,7 @@ retry:
        printk(KERN_ALERT "Unable to handle kernel paging request at "
               "virtual address %016lx\n", address);
        die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 
        /* We ran out of memory, or some other thing happened to us that
           made us unable to handle the page fault gracefully.  */
index 54abd87..91e757b 100644 (file)
@@ -334,7 +334,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
        if (panic_on_oops)
                panic("Fatal exception");
        if (signr)
-               do_exit(signr);
+               make_task_dead(signr);
 }
 
 /*
index efa4020..af51778 100644 (file)
@@ -125,7 +125,7 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
        show_pte(KERN_ALERT, mm, addr);
        die("Oops", regs, fsr);
        bust_spinlocks(0);
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 }
 
 /*
index f859cc8..21e69a9 100644 (file)
@@ -235,7 +235,7 @@ void die(const char *str, struct pt_regs *regs, int err)
        raw_spin_unlock_irqrestore(&die_lock, flags);
 
        if (ret != NOTIFY_STOP)
-               do_exit(SIGSEGV);
+               make_task_dead(SIGSEGV);
 }
 
 static void arm64_show_signal(int signo, const char *str)
index d09b21f..97a93ee 100644 (file)
@@ -302,7 +302,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
        show_pte(addr);
        die("Oops", regs, esr);
        bust_spinlocks(0);
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 }
 
 #ifdef CONFIG_KASAN_HW_TAGS
index cb2a0d9..5e2fb45 100644 (file)
@@ -294,7 +294,7 @@ bad_area:
                                __func__, opcode, rz, rx, imm, addr);
                show_regs(regs);
                bust_spinlocks(0);
-               do_exit(SIGKILL);
+               make_dead_task(SIGKILL);
        }
 
        force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
index 2020af8..b445c5a 100644 (file)
@@ -109,7 +109,7 @@ void die(struct pt_regs *regs, const char *str)
        if (panic_on_oops)
                panic("Fatal exception");
        if (ret != NOTIFY_STOP)
-               do_exit(SIGSEGV);
+               make_dead_task(SIGSEGV);
 }
 
 void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
index 466ad94..7215a46 100644 (file)
@@ -67,7 +67,7 @@ static inline void no_context(struct pt_regs *regs, unsigned long addr)
        pr_alert("Unable to handle kernel paging request at virtual "
                 "addr 0x%08lx, pc: 0x%08lx\n", addr, regs->pc);
        die(regs, "Oops");
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 }
 
 static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault)
index bdbe988..3d4e0bd 100644 (file)
@@ -106,7 +106,7 @@ void die(const char *str, struct pt_regs *fp, unsigned long err)
        dump(fp);
 
        spin_unlock_irq(&die_lock);
-       do_exit(SIGSEGV);
+       make_dead_task(SIGSEGV);
 }
 
 static int kstack_depth_to_print = 24;
index d4bc9c1..0223528 100644 (file)
@@ -51,7 +51,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
        printk(" at virtual address %08lx\n", address);
        if (!user_mode(regs))
                die("Oops", regs, error_code);
-       do_exit(SIGKILL);
+       make_dead_task(SIGKILL);
 
        return 1;
 }
index edfc35d..6dd6cf0 100644 (file)
@@ -214,7 +214,7 @@ int die(const char *str, struct pt_regs *regs, long err)
                panic("Fatal exception");
 
        oops_exit();
-       do_exit(err);
+       make_dead_task(err);
        return 0;
 }
 
index 5bfc79b..23c2036 100644 (file)
@@ -176,7 +176,7 @@ mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
        spin_unlock(&mca_bh_lock);
 
        /* This process is about to be killed itself */
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 }
 
 /**
index e13cb90..7536423 100644 (file)
@@ -85,7 +85,7 @@ die (const char *str, struct pt_regs *regs, long err)
        if (panic_on_oops)
                panic("Fatal exception");
 
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
        return 0;
 }
 
index 02de2e7..4796ccc 100644 (file)
@@ -259,7 +259,7 @@ retry:
                regs = NULL;
        bust_spinlocks(0);
        if (regs)
-               do_exit(SIGKILL);
+               make_task_dead(SIGKILL);
        return;
 
   out_of_memory:
index 34d6458..59fc63f 100644 (file)
@@ -1131,7 +1131,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
        pr_crit("%s: %08x\n", str, nr);
        show_registers(fp);
        add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
 
 asmlinkage void set_esp0(unsigned long ssp)
index ef46e77..fcb3a0d 100644 (file)
@@ -48,7 +48,7 @@ int send_fault_sig(struct pt_regs *regs)
                        pr_alert("Unable to handle kernel access");
                pr_cont(" at virtual address %p\n", addr);
                die_if_kernel("Oops", regs, 0 /*error_code*/);
-               do_exit(SIGKILL);
+               make_task_dead(SIGKILL);
        }
 
        return 1;
index 9087884..fd153d5 100644 (file)
@@ -44,10 +44,10 @@ void die(const char *str, struct pt_regs *fp, long err)
        pr_warn("Oops: %s, sig: %ld\n", str, err);
        show_regs(fp);
        spin_unlock_irq(&die_lock);
-       /* do_exit() should take care of panic'ing from an interrupt
+       /* make_task_dead() should take care of panic'ing from an interrupt
         * context so we don't handle it here
         */
-       do_exit(err);
+       make_task_dead(err);
 }
 
 /* for user application debugging */
index edd9343..afb2c95 100644 (file)
@@ -416,7 +416,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
        if (regs && kexec_should_crash(current))
                crash_kexec(regs);
 
-       do_exit(sig);
+       make_task_dead(sig);
 }
 
 extern struct exception_table_entry __start___dbe_table[];
index 9edd7ed..701c09a 100644 (file)
@@ -223,7 +223,7 @@ inline void handle_fpu_exception(struct pt_regs *regs)
                }
        } else if (fpcsr & FPCSR_mskRIT) {
                if (!user_mode(regs))
-                       do_exit(SIGILL);
+                       make_task_dead(SIGILL);
                si_signo = SIGILL;
        }
 
index f06421c..b90030e 100644 (file)
@@ -141,7 +141,7 @@ void die(const char *str, struct pt_regs *regs, int err)
 
        bust_spinlocks(0);
        spin_unlock_irq(&die_lock);
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
 
 EXPORT_SYMBOL(die);
@@ -240,7 +240,7 @@ void unhandled_interruption(struct pt_regs *regs)
        pr_emerg("unhandled_interruption\n");
        show_regs(regs);
        if (!user_mode(regs))
-               do_exit(SIGKILL);
+               make_task_dead(SIGKILL);
        force_sig(SIGKILL);
 }
 
@@ -251,7 +251,7 @@ void unhandled_exceptions(unsigned long entry, unsigned long addr,
                 addr, type);
        show_regs(regs);
        if (!user_mode(regs))
-               do_exit(SIGKILL);
+               make_task_dead(SIGKILL);
        force_sig(SIGKILL);
 }
 
@@ -278,7 +278,7 @@ void do_revinsn(struct pt_regs *regs)
        pr_emerg("Reserved Instruction\n");
        show_regs(regs);
        if (!user_mode(regs))
-               do_exit(SIGILL);
+               make_task_dead(SIGILL);
        force_sig(SIGILL);
 }
 
index 596986a..85ac49d 100644 (file)
@@ -37,10 +37,10 @@ void die(const char *str, struct pt_regs *regs, long err)
        show_regs(regs);
        spin_unlock_irq(&die_lock);
        /*
-        * do_exit() should take care of panic'ing from an interrupt
+        * make_task_dead() should take care of panic'ing from an interrupt
         * context so we don't handle it here
         */
-       do_exit(err);
+       make_task_dead(err);
 }
 
 void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
index aa1e709..9df1d85 100644 (file)
@@ -212,7 +212,7 @@ void die(const char *str, struct pt_regs *regs, long err)
        __asm__ __volatile__("l.nop   1");
        do {} while (1);
 #endif
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
 
 /* This is normally the 'Oops' routine */
index 6fe5a3e..70ace36 100644 (file)
@@ -268,7 +268,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
                panic("Fatal exception");
 
        oops_exit();
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
 
 /* gdb uses break 4,8 */
index 1174170..a08bb7c 100644 (file)
@@ -245,7 +245,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs,
 
        if (panic_on_oops)
                panic("Fatal exception");
-       do_exit(signr);
+       make_task_dead(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
 
@@ -792,9 +792,9 @@ int machine_check_generic(struct pt_regs *regs)
 void die_mce(const char *str, struct pt_regs *regs, long err)
 {
        /*
-        * The machine check wants to kill the interrupted context, but
-        * do_exit() checks for in_interrupt() and panics in that case, so
-        * exit the irq/nmi before calling die.
+        * The machine check wants to kill the interrupted context,
+        * but make_task_dead() checks for in_interrupt() and panics
+        * in that case, so exit the irq/nmi before calling die.
         */
        if (in_nmi())
                nmi_exit();
index 4102c97..6084bd9 100644 (file)
@@ -59,7 +59,7 @@ void die(struct pt_regs *regs, const char *str)
        if (panic_on_oops)
                panic("Fatal exception");
        if (ret != NOTIFY_STOP)
-               do_exit(SIGSEGV);
+               make_task_dead(SIGSEGV);
 }
 
 void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
index 7cfaf36..676a3f2 100644 (file)
@@ -31,7 +31,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
 
        bust_spinlocks(0);
        die(regs, "Oops");
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 }
 
 static inline void no_context(struct pt_regs *regs, unsigned long addr)
index db1bc00..272ef85 100644 (file)
@@ -224,5 +224,5 @@ void die(struct pt_regs *regs, const char *str)
        if (panic_on_oops)
                panic("Fatal exception: panic_on_oops");
        oops_exit();
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
index 383b479..d4f071e 100644 (file)
@@ -175,7 +175,7 @@ void __s390_handle_mcck(void)
                       "malfunction (code 0x%016lx).\n", mcck.mcck_code);
                printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
                       current->comm, current->pid);
-               do_exit(SIGSEGV);
+               make_task_dead(SIGSEGV);
        }
 }
 
index e76b221..361b764 100644 (file)
@@ -57,7 +57,7 @@ void die(const char *str, struct pt_regs *regs, long err)
        if (panic_on_oops)
                panic("Fatal exception");
 
-       do_exit(SIGSEGV);
+       make_task_dead(SIGSEGV);
 }
 
 void die_if_kernel(const char *str, struct pt_regs *regs, long err)
index 5630e5a..179aabf 100644 (file)
@@ -86,9 +86,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
        }
        printk("Instruction DUMP:");
        instruction_dump ((unsigned long *) regs->pc);
-       if(regs->psr & PSR_PS)
-               do_exit(SIGKILL);
-       do_exit(SIGSEGV);
+       make_task_dead((regs->psr & PSR_PS) ? SIGKILL : SIGSEGV);
 }
 
 void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
index 6863025..2107782 100644 (file)
@@ -2559,9 +2559,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
        }
        if (panic_on_oops)
                panic("Fatal exception");
-       if (regs->tstate & TSTATE_PRIV)
-               do_exit(SIGKILL);
-       do_exit(SIGSEGV);
+       make_task_dead((regs->tstate & TSTATE_PRIV)? SIGKILL : SIGSEGV);
 }
 EXPORT_SYMBOL(die_if_kernel);
 
index 6b44263..e309e71 100644 (file)
@@ -1239,14 +1239,14 @@ SYM_CODE_START(asm_exc_nmi)
 SYM_CODE_END(asm_exc_nmi)
 
 .pushsection .text, "ax"
-SYM_CODE_START(rewind_stack_do_exit)
+SYM_CODE_START(rewind_stack_and_make_dead)
        /* Prevent any naive code from trying to unwind to our caller. */
        xorl    %ebp, %ebp
 
        movl    PER_CPU_VAR(cpu_current_top_of_stack), %esi
        leal    -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
 
-       call    do_exit
+       call    make_task_dead
 1:     jmp 1b
-SYM_CODE_END(rewind_stack_do_exit)
+SYM_CODE_END(rewind_stack_and_make_dead)
 .popsection
index a3af2a9..9f1333a 100644 (file)
@@ -1487,7 +1487,7 @@ SYM_CODE_END(ignore_sysret)
 #endif
 
 .pushsection .text, "ax"
-SYM_CODE_START(rewind_stack_do_exit)
+SYM_CODE_START(rewind_stack_and_make_dead)
        UNWIND_HINT_FUNC
        /* Prevent any naive code from trying to unwind to our caller. */
        xorl    %ebp, %ebp
@@ -1496,6 +1496,6 @@ SYM_CODE_START(rewind_stack_do_exit)
        leaq    -PTREGS_SIZE(%rax), %rsp
        UNWIND_HINT_REGS
 
-       call    do_exit
-SYM_CODE_END(rewind_stack_do_exit)
+       call    make_task_dead
+SYM_CODE_END(rewind_stack_and_make_dead)
 .popsection
index ea4fe19..53de044 100644 (file)
@@ -351,7 +351,7 @@ unsigned long oops_begin(void)
 }
 NOKPROBE_SYMBOL(oops_begin);
 
-void __noreturn rewind_stack_do_exit(int signr);
+void __noreturn rewind_stack_and_make_dead(int signr);
 
 void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
 {
@@ -386,7 +386,7 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
         * reuse the task stack and that existing poisons are invalid.
         */
        kasan_unpoison_task_stack(current);
-       rewind_stack_do_exit(signr);
+       rewind_stack_and_make_dead(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
 
index 874b6ef..904086a 100644 (file)
@@ -552,5 +552,5 @@ void die(const char * str, struct pt_regs * regs, long err)
        if (panic_on_oops)
                panic("Fatal exception");
 
-       do_exit(err);
+       make_task_dead(err);
 }
index caae8e0..d351f1b 100644 (file)
@@ -59,6 +59,7 @@ extern void sched_post_fork(struct task_struct *p);
 extern void sched_dead(struct task_struct *p);
 
 void __noreturn do_task_dead(void);
+void __noreturn make_task_dead(int signr);
 
 extern void proc_caches_init(void);
 
index aefe744..5d1a507 100644 (file)
@@ -877,6 +877,15 @@ void __noreturn do_exit(long code)
 }
 EXPORT_SYMBOL_GPL(do_exit);
 
+void __noreturn make_task_dead(int signr)
+{
+       /*
+        * Take the task off the cpu after something catastrophic has
+        * happened.
+        */
+       do_exit(signr);
+}
+
 void complete_and_exit(struct completion *comp, long code)
 {
        if (comp)
index 308c880..82ade76 100644 (file)
@@ -169,6 +169,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
                "panic",
                "do_exit",
                "do_task_dead",
+               "make_task_dead",
                "__module_put_and_exit",
                "complete_and_exit",
                "__reiserfs_panic",
@@ -176,7 +177,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
                "fortify_panic",
                "usercopy_abort",
                "machine_real_restart",
-               "rewind_stack_do_exit",
+               "rewind_stack_and_make_dead"
                "kunit_try_catch_throw",
                "xen_start_kernel",
                "cpu_bringup_and_idle",