exit: Add and use make_task_dead.
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>
This commit is contained in:
parent
2f87e25512
commit
9a18c9c833
@ -192,7 +192,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
|
|||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_MATHEMU
|
#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",
|
printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
|
||||||
pc, va, opcode, reg);
|
pc, va, opcode, reg);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
|
|
||||||
got_exception:
|
got_exception:
|
||||||
/* Ok, we caught the exception, but we don't want it. Is there
|
/* Ok, we caught the exception, but we don't want it. Is there
|
||||||
@ -632,7 +632,7 @@ got_exception:
|
|||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -206,7 +206,7 @@ retry:
|
|||||||
printk(KERN_ALERT "Unable to handle kernel paging request at "
|
printk(KERN_ALERT "Unable to handle kernel paging request at "
|
||||||
"virtual address %016lx\n", address);
|
"virtual address %016lx\n", address);
|
||||||
die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
|
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
|
/* We ran out of memory, or some other thing happened to us that
|
||||||
made us unable to handle the page fault gracefully. */
|
made us unable to handle the page fault gracefully. */
|
||||||
|
@ -341,7 +341,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
|||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
if (signr)
|
if (signr)
|
||||||
do_exit(signr);
|
make_task_dead(signr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -124,7 +124,7 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
|
|||||||
show_pte(KERN_ALERT, mm, addr);
|
show_pte(KERN_ALERT, mm, addr);
|
||||||
die("Oops", regs, fsr);
|
die("Oops", regs, fsr);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -202,7 +202,7 @@ void die(const char *str, struct pt_regs *regs, int err)
|
|||||||
raw_spin_unlock_irqrestore(&die_lock, flags);
|
raw_spin_unlock_irqrestore(&die_lock, flags);
|
||||||
|
|
||||||
if (ret != NOTIFY_STOP)
|
if (ret != NOTIFY_STOP)
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arm64_show_signal(int signo, const char *str)
|
static void arm64_show_signal(int signo, const char *str)
|
||||||
|
@ -296,7 +296,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
|
|||||||
show_pte(addr);
|
show_pte(addr);
|
||||||
die("Oops", regs, esr);
|
die("Oops", regs, esr);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __do_kernel_fault(unsigned long addr, unsigned int esr,
|
static void __do_kernel_fault(unsigned long addr, unsigned int esr,
|
||||||
|
@ -294,7 +294,7 @@ bad_area:
|
|||||||
__func__, opcode, rz, rx, imm, addr);
|
__func__, opcode, rz, rx, imm, addr);
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
do_exit(SIGKILL);
|
make_dead_task(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
|
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
|
||||||
|
@ -85,7 +85,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, int nr)
|
|||||||
pr_err("%s: %08x\n", str, nr);
|
pr_err("%s: %08x\n", str, nr);
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
do_exit(SIGSEGV);
|
make_dead_task(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void buserr(struct pt_regs *regs)
|
void buserr(struct pt_regs *regs)
|
||||||
|
@ -110,7 +110,7 @@ void die(const char *str, struct pt_regs *fp, unsigned long err)
|
|||||||
dump(fp);
|
dump(fp);
|
||||||
|
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
do_exit(SIGSEGV);
|
make_dead_task(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kstack_depth_to_print = 24;
|
static int kstack_depth_to_print = 24;
|
||||||
|
@ -52,7 +52,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|||||||
printk(" at virtual address %08lx\n", address);
|
printk(" at virtual address %08lx\n", address);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
die("Oops", regs, error_code);
|
die("Oops", regs, error_code);
|
||||||
do_exit(SIGKILL);
|
make_dead_task(SIGKILL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ int die(const char *str, struct pt_regs *regs, long err)
|
|||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
oops_exit();
|
oops_exit();
|
||||||
do_exit(err);
|
make_dead_task(err);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/sched/task.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/kallsyms.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);
|
spin_unlock(&mca_bh_lock);
|
||||||
|
|
||||||
/* This process is about to be killed itself */
|
/* This process is about to be killed itself */
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +85,7 @@ die (const char *str, struct pt_regs *regs, long err)
|
|||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ retry:
|
|||||||
regs = NULL;
|
regs = NULL;
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
if (regs)
|
if (regs)
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
out_of_memory:
|
out_of_memory:
|
||||||
|
@ -1139,7 +1139,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
|
|||||||
pr_crit("%s: %08x\n", str, nr);
|
pr_crit("%s: %08x\n", str, nr);
|
||||||
show_registers(fp);
|
show_registers(fp);
|
||||||
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void set_esp0(unsigned long ssp)
|
asmlinkage void set_esp0(unsigned long ssp)
|
||||||
|
@ -48,7 +48,7 @@ int send_fault_sig(struct pt_regs *regs)
|
|||||||
pr_alert("Unable to handle kernel access");
|
pr_alert("Unable to handle kernel access");
|
||||||
pr_cont(" at virtual address %p\n", addr);
|
pr_cont(" at virtual address %p\n", addr);
|
||||||
die_if_kernel("Oops", regs, 0 /*error_code*/);
|
die_if_kernel("Oops", regs, 0 /*error_code*/);
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -44,10 +44,10 @@ void die(const char *str, struct pt_regs *fp, long err)
|
|||||||
pr_warn("Oops: %s, sig: %ld\n", str, err);
|
pr_warn("Oops: %s, sig: %ld\n", str, err);
|
||||||
show_regs(fp);
|
show_regs(fp);
|
||||||
spin_unlock_irq(&die_lock);
|
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
|
* context so we don't handle it here
|
||||||
*/
|
*/
|
||||||
do_exit(err);
|
make_task_dead(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for user application debugging */
|
/* for user application debugging */
|
||||||
|
@ -415,7 +415,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
|
|||||||
if (regs && kexec_should_crash(current))
|
if (regs && kexec_should_crash(current))
|
||||||
crash_kexec(regs);
|
crash_kexec(regs);
|
||||||
|
|
||||||
do_exit(sig);
|
make_task_dead(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern struct exception_table_entry __start___dbe_table[];
|
extern struct exception_table_entry __start___dbe_table[];
|
||||||
|
@ -223,7 +223,7 @@ inline void handle_fpu_exception(struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
} else if (fpcsr & FPCSR_mskRIT) {
|
} else if (fpcsr & FPCSR_mskRIT) {
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGILL);
|
make_task_dead(SIGILL);
|
||||||
si_signo = SIGILL;
|
si_signo = SIGILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ void die(const char *str, struct pt_regs *regs, int err)
|
|||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(die);
|
EXPORT_SYMBOL(die);
|
||||||
@ -288,7 +288,7 @@ void unhandled_interruption(struct pt_regs *regs)
|
|||||||
pr_emerg("unhandled_interruption\n");
|
pr_emerg("unhandled_interruption\n");
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
force_sig(SIGKILL);
|
force_sig(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +299,7 @@ void unhandled_exceptions(unsigned long entry, unsigned long addr,
|
|||||||
addr, type);
|
addr, type);
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
force_sig(SIGKILL);
|
force_sig(SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ void do_revinsn(struct pt_regs *regs)
|
|||||||
pr_emerg("Reserved Instruction\n");
|
pr_emerg("Reserved Instruction\n");
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
do_exit(SIGILL);
|
make_task_dead(SIGILL);
|
||||||
force_sig(SIGILL);
|
force_sig(SIGILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,10 +37,10 @@ void die(const char *str, struct pt_regs *regs, long err)
|
|||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
spin_unlock_irq(&die_lock);
|
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
|
* 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)
|
void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
|
||||||
|
@ -218,7 +218,7 @@ void die(const char *str, struct pt_regs *regs, long err)
|
|||||||
__asm__ __volatile__("l.nop 1");
|
__asm__ __volatile__("l.nop 1");
|
||||||
do {} while (1);
|
do {} while (1);
|
||||||
#endif
|
#endif
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is normally the 'Oops' routine */
|
/* This is normally the 'Oops' routine */
|
||||||
|
@ -268,7 +268,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
|
|||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
oops_exit();
|
oops_exit();
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gdb uses break 4,8 */
|
/* gdb uses break 4,8 */
|
||||||
|
@ -246,7 +246,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs,
|
|||||||
|
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
do_exit(signr);
|
make_task_dead(signr);
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(oops_end);
|
NOKPROBE_SYMBOL(oops_end);
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ void die(struct pt_regs *regs, const char *str)
|
|||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
if (ret != NOTIFY_STOP)
|
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)
|
void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
|
||||||
|
@ -189,7 +189,7 @@ no_context:
|
|||||||
(addr < PAGE_SIZE) ? "NULL pointer dereference" :
|
(addr < PAGE_SIZE) ? "NULL pointer dereference" :
|
||||||
"paging request", addr);
|
"paging request", addr);
|
||||||
die(regs, "Oops");
|
die(regs, "Oops");
|
||||||
do_exit(SIGKILL);
|
make_task_dead(SIGKILL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We ran out of memory, call the OOM killer, and return the userspace
|
* We ran out of memory, call the OOM killer, and return the userspace
|
||||||
|
@ -210,5 +210,5 @@ void die(struct pt_regs *regs, const char *str)
|
|||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception: panic_on_oops");
|
panic("Fatal exception: panic_on_oops");
|
||||||
oops_exit();
|
oops_exit();
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ void s390_handle_mcck(void)
|
|||||||
"malfunction (code 0x%016lx).\n", mcck.mcck_code);
|
"malfunction (code 0x%016lx).\n", mcck.mcck_code);
|
||||||
printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
|
printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
|
||||||
current->comm, current->pid);
|
current->comm, current->pid);
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(s390_handle_mcck);
|
EXPORT_SYMBOL_GPL(s390_handle_mcck);
|
||||||
|
@ -57,7 +57,7 @@ void die(const char *str, struct pt_regs *regs, long err)
|
|||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
do_exit(SIGSEGV);
|
make_task_dead(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void die_if_kernel(const char *str, struct pt_regs *regs, long err)
|
void die_if_kernel(const char *str, struct pt_regs *regs, long err)
|
||||||
|
@ -86,9 +86,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
printk("Instruction DUMP:");
|
printk("Instruction DUMP:");
|
||||||
instruction_dump ((unsigned long *) regs->pc);
|
instruction_dump ((unsigned long *) regs->pc);
|
||||||
if(regs->psr & PSR_PS)
|
make_task_dead((regs->psr & PSR_PS) ? SIGKILL : SIGSEGV);
|
||||||
do_exit(SIGKILL);
|
|
||||||
do_exit(SIGSEGV);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
|
void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
|
||||||
|
@ -2564,9 +2564,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
|
|||||||
}
|
}
|
||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
if (regs->tstate & TSTATE_PRIV)
|
make_task_dead((regs->tstate & TSTATE_PRIV)? SIGKILL : SIGSEGV);
|
||||||
do_exit(SIGKILL);
|
|
||||||
do_exit(SIGSEGV);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(die_if_kernel);
|
EXPORT_SYMBOL(die_if_kernel);
|
||||||
|
|
||||||
|
@ -1659,13 +1659,13 @@ ENTRY(async_page_fault)
|
|||||||
END(async_page_fault)
|
END(async_page_fault)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ENTRY(rewind_stack_do_exit)
|
ENTRY(rewind_stack_and_make_dead)
|
||||||
/* Prevent any naive code from trying to unwind to our caller. */
|
/* Prevent any naive code from trying to unwind to our caller. */
|
||||||
xorl %ebp, %ebp
|
xorl %ebp, %ebp
|
||||||
|
|
||||||
movl PER_CPU_VAR(cpu_current_top_of_stack), %esi
|
movl PER_CPU_VAR(cpu_current_top_of_stack), %esi
|
||||||
leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
|
leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
|
||||||
|
|
||||||
call do_exit
|
call make_task_dead
|
||||||
1: jmp 1b
|
1: jmp 1b
|
||||||
END(rewind_stack_do_exit)
|
END(rewind_stack_and_make_dead)
|
||||||
|
@ -1757,7 +1757,7 @@ ENTRY(ignore_sysret)
|
|||||||
END(ignore_sysret)
|
END(ignore_sysret)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ENTRY(rewind_stack_do_exit)
|
ENTRY(rewind_stack_and_make_dead)
|
||||||
UNWIND_HINT_FUNC
|
UNWIND_HINT_FUNC
|
||||||
/* Prevent any naive code from trying to unwind to our caller. */
|
/* Prevent any naive code from trying to unwind to our caller. */
|
||||||
xorl %ebp, %ebp
|
xorl %ebp, %ebp
|
||||||
@ -1766,5 +1766,5 @@ ENTRY(rewind_stack_do_exit)
|
|||||||
leaq -PTREGS_SIZE(%rax), %rsp
|
leaq -PTREGS_SIZE(%rax), %rsp
|
||||||
UNWIND_HINT_REGS
|
UNWIND_HINT_REGS
|
||||||
|
|
||||||
call do_exit
|
call make_task_dead
|
||||||
END(rewind_stack_do_exit)
|
END(rewind_stack_and_make_dead)
|
||||||
|
@ -326,7 +326,7 @@ unsigned long oops_begin(void)
|
|||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(oops_begin);
|
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)
|
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.
|
* reuse the task stack and that existing poisons are invalid.
|
||||||
*/
|
*/
|
||||||
kasan_unpoison_task_stack(current);
|
kasan_unpoison_task_stack(current);
|
||||||
rewind_stack_do_exit(signr);
|
rewind_stack_and_make_dead(signr);
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(oops_end);
|
NOKPROBE_SYMBOL(oops_end);
|
||||||
|
|
||||||
|
@ -543,5 +543,5 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||||||
if (panic_on_oops)
|
if (panic_on_oops)
|
||||||
panic("Fatal exception");
|
panic("Fatal exception");
|
||||||
|
|
||||||
do_exit(err);
|
make_task_dead(err);
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ extern int sched_fork(unsigned long clone_flags, struct task_struct *p);
|
|||||||
extern void sched_dead(struct task_struct *p);
|
extern void sched_dead(struct task_struct *p);
|
||||||
|
|
||||||
void __noreturn do_task_dead(void);
|
void __noreturn do_task_dead(void);
|
||||||
|
void __noreturn make_task_dead(int signr);
|
||||||
|
|
||||||
extern void proc_caches_init(void);
|
extern void proc_caches_init(void);
|
||||||
|
|
||||||
|
@ -864,6 +864,15 @@ void __noreturn do_exit(long code)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(do_exit);
|
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)
|
void complete_and_exit(struct completion *comp, long code)
|
||||||
{
|
{
|
||||||
if (comp)
|
if (comp)
|
||||||
|
@ -136,6 +136,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
|
|||||||
"panic",
|
"panic",
|
||||||
"do_exit",
|
"do_exit",
|
||||||
"do_task_dead",
|
"do_task_dead",
|
||||||
|
"make_task_dead",
|
||||||
"__module_put_and_exit",
|
"__module_put_and_exit",
|
||||||
"complete_and_exit",
|
"complete_and_exit",
|
||||||
"__reiserfs_panic",
|
"__reiserfs_panic",
|
||||||
@ -143,7 +144,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
|
|||||||
"fortify_panic",
|
"fortify_panic",
|
||||||
"usercopy_abort",
|
"usercopy_abort",
|
||||||
"machine_real_restart",
|
"machine_real_restart",
|
||||||
"rewind_stack_do_exit",
|
"rewind_stack_and_make_dead"
|
||||||
"cpu_bringup_and_idle",
|
"cpu_bringup_and_idle",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user