If an attacker can cause a controlled kernel stack overflow, overwriting the restart block is a very juicy exploit target. This is because the restart_block is held in the same memory allocation as the kernel stack. Moving the restart block to struct task_struct prevents this exploit by making the restart_block harder to locate. Note that there are other fields in thread_info that are also easy targets, at least on some architectures. It's also a decent simplification, since the restart code is more or less identical on all architectures. [james.hogan@imgtec.com: metag: align thread_info::supervisor_stack] Signed-off-by: Andy Lutomirski <luto@amacapital.net> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Kees Cook <keescook@chromium.org> Cc: David Miller <davem@davemloft.net> Acked-by: Richard Weinberger <richard@nod.at> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Matt Turner <mattst88@gmail.com> Cc: Vineet Gupta <vgupta@synopsys.com> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Haavard Skinnemoen <hskinnemoen@gmail.com> Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no> Cc: Steven Miao <realmz6@gmail.com> Cc: Mark Salter <msalter@redhat.com> Cc: Aurelien Jacquiot <a-jacquiot@ti.com> Cc: Mikael Starvik <starvik@axis.com> Cc: Jesper Nilsson <jesper.nilsson@axis.com> Cc: David Howells <dhowells@redhat.com> Cc: Richard Kuo <rkuo@codeaurora.org> Cc: "Luck, Tony" <tony.luck@intel.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Michal Simek <monstr@monstr.eu> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Jonas Bonn <jonas@southpole.se> Cc: "James E.J. Bottomley" <jejb@parisc-linux.org> Cc: Helge Deller <deller@gmx.de> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc) Tested-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc) Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Chen Liqin <liqin.linux@gmail.com> Cc: Lennox Wu <lennox.wu@gmail.com> Cc: Chris Metcalf <cmetcalf@ezchip.com> Cc: Guan Xuetao <gxt@mprc.pku.edu.cn> Cc: Chris Zankel <chris@zankel.net> Cc: Max Filippov <jcmvbkbc@gmail.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Guenter Roeck <linux@roeck-us.net> Signed-off-by: James Hogan <james.hogan@imgtec.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
		
			
				
	
	
		
			138 lines
		
	
	
	
		
			4.2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			4.2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Based on arch/arm/include/asm/thread_info.h
 | 
						|
 *
 | 
						|
 * Copyright (C) 2002 Russell King.
 | 
						|
 * Copyright (C) 2012 ARM Ltd.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU General Public License version 2 as
 | 
						|
 * published by the Free Software Foundation.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 */
 | 
						|
#ifndef __ASM_THREAD_INFO_H
 | 
						|
#define __ASM_THREAD_INFO_H
 | 
						|
 | 
						|
#ifdef __KERNEL__
 | 
						|
 | 
						|
#include <linux/compiler.h>
 | 
						|
 | 
						|
#ifndef CONFIG_ARM64_64K_PAGES
 | 
						|
#define THREAD_SIZE_ORDER	2
 | 
						|
#endif
 | 
						|
 | 
						|
#define THREAD_SIZE		16384
 | 
						|
#define THREAD_START_SP		(THREAD_SIZE - 16)
 | 
						|
 | 
						|
#ifndef __ASSEMBLY__
 | 
						|
 | 
						|
struct task_struct;
 | 
						|
struct exec_domain;
 | 
						|
 | 
						|
#include <asm/types.h>
 | 
						|
 | 
						|
typedef unsigned long mm_segment_t;
 | 
						|
 | 
						|
/*
 | 
						|
 * low level task data that entry.S needs immediate access to.
 | 
						|
 * __switch_to() assumes cpu_context follows immediately after cpu_domain.
 | 
						|
 */
 | 
						|
struct thread_info {
 | 
						|
	unsigned long		flags;		/* low level flags */
 | 
						|
	mm_segment_t		addr_limit;	/* address limit */
 | 
						|
	struct task_struct	*task;		/* main task structure */
 | 
						|
	struct exec_domain	*exec_domain;	/* execution domain */
 | 
						|
	int			preempt_count;	/* 0 => preemptable, <0 => bug */
 | 
						|
	int			cpu;		/* cpu */
 | 
						|
};
 | 
						|
 | 
						|
#define INIT_THREAD_INFO(tsk)						\
 | 
						|
{									\
 | 
						|
	.task		= &tsk,						\
 | 
						|
	.exec_domain	= &default_exec_domain,				\
 | 
						|
	.flags		= 0,						\
 | 
						|
	.preempt_count	= INIT_PREEMPT_COUNT,				\
 | 
						|
	.addr_limit	= KERNEL_DS,					\
 | 
						|
}
 | 
						|
 | 
						|
#define init_thread_info	(init_thread_union.thread_info)
 | 
						|
#define init_stack		(init_thread_union.stack)
 | 
						|
 | 
						|
/*
 | 
						|
 * how to get the current stack pointer from C
 | 
						|
 */
 | 
						|
register unsigned long current_stack_pointer asm ("sp");
 | 
						|
 | 
						|
/*
 | 
						|
 * how to get the thread information struct from C
 | 
						|
 */
 | 
						|
static inline struct thread_info *current_thread_info(void) __attribute_const__;
 | 
						|
 | 
						|
static inline struct thread_info *current_thread_info(void)
 | 
						|
{
 | 
						|
	return (struct thread_info *)
 | 
						|
		(current_stack_pointer & ~(THREAD_SIZE - 1));
 | 
						|
}
 | 
						|
 | 
						|
#define thread_saved_pc(tsk)	\
 | 
						|
	((unsigned long)(tsk->thread.cpu_context.pc))
 | 
						|
#define thread_saved_sp(tsk)	\
 | 
						|
	((unsigned long)(tsk->thread.cpu_context.sp))
 | 
						|
#define thread_saved_fp(tsk)	\
 | 
						|
	((unsigned long)(tsk->thread.cpu_context.fp))
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * thread information flags:
 | 
						|
 *  TIF_SYSCALL_TRACE	- syscall trace active
 | 
						|
 *  TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
 | 
						|
 *  TIF_SYSCALL_AUDIT	- syscall auditing
 | 
						|
 *  TIF_SECOMP		- syscall secure computing
 | 
						|
 *  TIF_SIGPENDING	- signal pending
 | 
						|
 *  TIF_NEED_RESCHED	- rescheduling necessary
 | 
						|
 *  TIF_NOTIFY_RESUME	- callback before returning to user
 | 
						|
 *  TIF_USEDFPU		- FPU was used by this task this quantum (SMP)
 | 
						|
 */
 | 
						|
#define TIF_SIGPENDING		0
 | 
						|
#define TIF_NEED_RESCHED	1
 | 
						|
#define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
 | 
						|
#define TIF_FOREIGN_FPSTATE	3	/* CPU's FP state is not current's */
 | 
						|
#define TIF_NOHZ		7
 | 
						|
#define TIF_SYSCALL_TRACE	8
 | 
						|
#define TIF_SYSCALL_AUDIT	9
 | 
						|
#define TIF_SYSCALL_TRACEPOINT	10
 | 
						|
#define TIF_SECCOMP		11
 | 
						|
#define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 | 
						|
#define TIF_FREEZE		19
 | 
						|
#define TIF_RESTORE_SIGMASK	20
 | 
						|
#define TIF_SINGLESTEP		21
 | 
						|
#define TIF_32BIT		22	/* 32bit process */
 | 
						|
#define TIF_SWITCH_MM		23	/* deferred switch_mm */
 | 
						|
 | 
						|
#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 | 
						|
#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 | 
						|
#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 | 
						|
#define _TIF_FOREIGN_FPSTATE	(1 << TIF_FOREIGN_FPSTATE)
 | 
						|
#define _TIF_NOHZ		(1 << TIF_NOHZ)
 | 
						|
#define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 | 
						|
#define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 | 
						|
#define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
 | 
						|
#define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 | 
						|
#define _TIF_32BIT		(1 << TIF_32BIT)
 | 
						|
 | 
						|
#define _TIF_WORK_MASK		(_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
 | 
						|
				 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE)
 | 
						|
 | 
						|
#define _TIF_SYSCALL_WORK	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
 | 
						|
				 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
 | 
						|
				 _TIF_NOHZ)
 | 
						|
 | 
						|
#endif /* __KERNEL__ */
 | 
						|
#endif /* __ASM_THREAD_INFO_H */
 |