Linux 5.10 start_kernel 分析 —— set_task_stack_end_magic

本文详细分析了Linux 5.10中start_kernel函数如何进行栈溢出检测,探讨了thread_info、thread_union、task_struct的内存布局,以及它们在开启或关闭特定配置时的不同情况。重点关注了如何确定栈的结束位置,涉及到CONFIG_THREAD_INFO_IN_TASK和CONFIG_STACK_GROWSUP等配置的影响。
摘要由CSDN通过智能技术生成

==>开始

void set_task_stack_end_magic(struct task_struct *tsk)
{
   
	unsigned long *stackend;

	stackend = end_of_stack(tsk);
	*stackend = STACK_END_MAGIC;	/* for overflow detection */
}

从注释可以看出,设置魔数的目的是为了进行栈溢出检测(for overflow detection),STACK_END_MAGIC 为栈底魔数,其定义在 include/uapi/linux/magic.h 中的 67 行,和其他魔数定义在一起

#define STACK_END_MAGIC		0x57AC6E9D

显然 end_of_stack 函数接受一个 task_struct 类型的结构体指针,并返回一个 unsigned long 型的指针,指针指向栈底最后一个 long 大小的位置。其定义在 include/linux/sched/task_stack.h 中,如果开启配置 CONFIG_THREAD_INFO_IN_TASK 则此函数为

static inline unsigned long *end_of_stack(const struct task_struct *task)
{
   
	return task->stack;
}

若没有开启 CONFIG_THREAD_INFO_IN_TASK,则此函数为

/*
 * Return the address of the last usable long on the stack.
 *
 * When the stack grows down, this is just above the thread
 * info struct. Going any lower will corrupt the threadinfo.
 *
 * When the stack grows up, this is the highest address.
 * Beyond that position, we corrupt data on the next page.
 */
static inline unsigned long *end_of_stack(struct task_struct *p)
{
   
#ifdef CONFIG_STACK_GROWSUP
	return (unsigned long *)((unsigned long)task_thread_info(p) + THREAD_SIZE) - 1;
#else
	return (unsigned long *)(task_thread_info(p) + 1);
#endif
}

其中配置 CONFIG_STACK_GROWSUP 配置的意思是内核栈向上扩张。而没有开启此配置时,内核栈是向下扩张的。为了确认内核栈的具体位置,需要搞清楚,task_struct thread_info thread_union 三者的具体关系。

==>thread_info

thread_info 结构体是个架构相关的结构,所以定义在相关架构的目录下,在 arm64 架构下,thread_info 结构体定义在 arch/arm64/include/asm/thread_info.h

/*
 * low level task data that entry.S needs immediate access to.
 */
struct thread_info {
   
	unsigned long		flags;		/* low level flags */
	mm_segment_t		addr_limit;	/* address limit */
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值