]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
exit: Add and use make_task_dead.
authorEric W. Biederman <ebiederm@xmission.com>
Fri, 3 Feb 2023 00:27:05 +0000 (16:27 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Feb 2023 06:49:45 +0000 (07:49 +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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
35 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/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/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 bc9627698796ee474a1290dd9c199ff13b48a893..22f5c27b96b7cbb152fe826d0c75763b3a1ee080 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 188fc9256baf16824431cb273f588daa219b2521..6ce67b05412ec0dd7e395d40502be3c8a53091c0 100644 (file)
@@ -206,7 +206,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 d49fafd2b865ff593b88500e2c69077c9b9f231e..02a4aea52fb05b2bb9a56fb5760a2afd91bc587e 100644 (file)
@@ -344,7 +344,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 a9ee0d9dc740a0582028a447d969d9ff0e39afbb..8457384139cb80b81516664dd0387cac1cdf5ef8 100644 (file)
@@ -149,7 +149,7 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
        show_pte(mm, addr);
        die("Oops", regs, fsr);
        bust_spinlocks(0);
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 }
 
 /*
index 965595fe6804578e2b0bb095f4a62699c59f98de..20f896b27a44710e3ded4a60679a7dc253e64d48 100644 (file)
@@ -224,7 +224,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 bool show_unhandled_signals_ratelimited(void)
index b046006a387ffdf14d934fc8630b247c6a93dda9..0d2be8eb87ec8e95d27620f5da5df750fb25ae34 100644 (file)
@@ -268,7 +268,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);
 }
 
 static void __do_kernel_fault(unsigned long addr, unsigned int esr,
index e47a9e0dc278fa99abb1319f9503d8a0c2f33ca9..a284c126f07a67938c916134adf5fa08d4e8b034 100644 (file)
@@ -110,7 +110,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 fabffb83930af24e214d27637eb90deb976492d0..a8d8fc63780e4989b280ea7341d365bf71038a1c 100644 (file)
@@ -52,7 +52,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 91ee04842c22cba5c6208088a86bc92b34eb28b7..ac8154992f3eb2001e5a75bd2f233fb20b11ea48 100644 (file)
@@ -234,7 +234,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 06419a95af309863a8f5eb83708c3dad30b188ac..07353029b003a91e7d0027a417f989e67ad71add 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/sched/task.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kallsyms.h>
@@ -176,7 +177,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 c6f4932073a1857f496b08149dfacbe31b6778c0..32c2877b3c0ad77598ec5c0827a88d549fa586f7 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 a9d55ad8d67be8e1bb4ef0c0010cda5742637a43..0b072af7e20d8fec3cb59bbb750685c3dca5206b 100644 (file)
@@ -302,7 +302,7 @@ retry:
                regs = NULL;
        bust_spinlocks(0);
        if (regs)
-               do_exit(SIGKILL);
+               make_task_dead(SIGKILL);
        return;
 
   out_of_memory:
index b2fd000b92857b0eb607fe654d6e13ebc57f3a1f..9b70a7f5e7058f9c52441f44fedb5ef224894aa4 100644 (file)
@@ -1139,7 +1139,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 9b6163c05a754f8d86e6508eba4fd77483f71892..fc3aea6dcaa77f25e2e631208fc3ed76710900c5 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 eafff21fcb0e646e25fdee6f2f75640b0c01ad2c..182402db6b043103284294569dba97f727fe325f 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 0ca4185cc5e38837cabbccb937896170360bf295..01c85d37c47ab6685368e975040a16543fe2a563 100644 (file)
@@ -412,7 +412,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 1496aab48998817c00cb175dbd8b09b3453d73dd..a811f286bc85cc427490bd7a9301634d3eb4493a 100644 (file)
@@ -183,7 +183,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);
@@ -286,7 +286,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, current);
 }
 
@@ -297,7 +297,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, current);
 }
 
@@ -324,7 +324,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, current);
 }
 
index 3bc3cd22b750e70216e2f79890a8034ff61f59fb..dc6c270a355b63fdd1d419cc48d36a80b43d5fcf 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 d8981cbb852a5f1fc1ea80667df3ed451579d13c..dfa3db1bccef4c361703ae23e6d9b9e4e1f7825d 100644 (file)
@@ -224,7 +224,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 d7a66d8525091d37aade4064f3e445a1c68934ae..5d9cf726e4ecd6854c2622100026deb277d819f7 100644 (file)
@@ -265,7 +265,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 2379c4bf3979ee69cbadfa16e76f6a0db0e951d3..63c751ce130a5cf4e763342205f741b9993d3939 100644 (file)
@@ -251,7 +251,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs,
                panic("Fatal exception in interrupt");
        if (panic_on_oops)
                panic("Fatal exception");
-       do_exit(signr);
+       make_task_dead(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
 
index 7c65750508f25ae4222cb4b4a98c339df3c00934..9b736e616131d4cb07ef545f513927e1d3661fd2 100644 (file)
@@ -64,7 +64,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,
index 523dbfbac03ddedac0709a15102bc4e460b93d1f..7b5f110f8191ad96a1685997c10934303813c7eb 100644 (file)
@@ -200,7 +200,7 @@ no_context:
                (addr < PAGE_SIZE) ? "NULL pointer dereference" :
                "paging request", addr);
        die(regs, "Oops");
-       do_exit(SIGKILL);
+       make_task_dead(SIGKILL);
 
        /*
         * We ran out of memory, call the OOM killer, and return the userspace
index 5b23c4f6e50cd452177477105b914774d67898ad..7b21019096f4493699a63f17e44c0296e423f7ce 100644 (file)
@@ -187,5 +187,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 8c867b43c8ebc5b60469b52700ad6198daf1d874..471a965ae75a4fdb836fbdbb1eedaf29a6043d5e 100644 (file)
@@ -179,7 +179,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);
        }
 }
 EXPORT_SYMBOL_GPL(s390_handle_mcck);
index 8b49cced663dc54a387144866811fa8f16929893..5fafbef7849b105b059f99e7c4241a2a08207c22 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 bcdfc6168dd58e9d9aca04e8fe2e8542ab20fb89..ec7fcfbad06c06c1f0afc9f82da144c8f6b06e45 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 86879c28910b7884a7480c157e68a8ceecca3419..1a338784a37c88cfd11401a0069a2c1d0e749d1e 100644 (file)
@@ -2565,9 +2565,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 78b308f2f2ea68555e3ef47db83c94dbf87b5944..e6c258bf951162ad464c7977ce98aa9671e66265 100644 (file)
@@ -1500,13 +1500,13 @@ ENTRY(async_page_fault)
 END(async_page_fault)
 #endif
 
-ENTRY(rewind_stack_do_exit)
+ENTRY(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
-END(rewind_stack_do_exit)
+END(rewind_stack_and_make_dead)
index 55e0538711387d037538236b211d3eab919a8d1e..ef693d3689aa70a53538c6552e9c71c41ea6114f 100644 (file)
@@ -1762,7 +1762,7 @@ ENTRY(ignore_sysret)
        sysretl
 END(ignore_sysret)
 
-ENTRY(rewind_stack_do_exit)
+ENTRY(rewind_stack_and_make_dead)
        UNWIND_HINT_FUNC
        /* Prevent any naive code from trying to unwind to our caller. */
        xorl    %ebp, %ebp
@@ -1771,5 +1771,5 @@ ENTRY(rewind_stack_do_exit)
        leaq    -PTREGS_SIZE(%rax), %rsp
        UNWIND_HINT_REGS
 
-       call    do_exit
-END(rewind_stack_do_exit)
+       call    make_task_dead
+END(rewind_stack_and_make_dead)
index 2b5886401e5f4eb2c221f813675927a53cc97d61..2b17a5cec0997c01afa6b778a6a4713c5284d34c 100644 (file)
@@ -326,7 +326,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)
 {
@@ -361,7 +361,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 86507fa7c2d7cdd1382df7f41bb5afd730a541c2..2ae5c505894bd5a2655122baa0a7f69ae4609fad 100644 (file)
@@ -542,5 +542,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 91401309b1aa224c4a0abfd131308c810471c0cd..0ee9aab3e30919d2c165fe3ccbf34996ebca1ce8 100644 (file)
@@ -36,6 +36,7 @@ extern int sched_fork(unsigned long clone_flags, 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 908e7a33e1fcb38f40cf8de3eed283e548000e96..2147bbc2c7c328f57e933d2280cd4ce67959c6ef 100644 (file)
@@ -922,6 +922,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 c0ab27368a3455aaf0facbc6d9b7efdc5882859e..04771905571078348b1970f55783992e39b35149 100644 (file)
@@ -159,6 +159,7 @@ static int __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",
                "kvm_spurious_fault",
@@ -167,7 +168,7 @@ static int __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"
        };
 
        if (func->bind == STB_WEAK)