kernel space 中调用系统调用对地址空间检查

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tiantao2012/article/details/83511819
在内核中调用系统调用,需要使用get_fs,set_fs来对其保护,因为这些函数会检查参数地址是不是
用户空间的,但是很显然,我们是在内核空间中调用这些系统调用。
#define get_ds()	(KERNEL_DS)
可以看到这里的get_fs 直接返回的是当前进程的地址限制,用户进程和内核进程肯定是不一样的
#define get_fs()	(current_thread_info()->addr_limit)
而set_fs稍微复杂点分析如下:
static inline void set_fs(mm_segment_t fs)
{
	#首先设置当前进程的地址限制,这样一般是通过get_ds得到的
	current_thread_info()->addr_limit = fs;

	/*
	 * Prevent a mispredicted conditional call to set_fs from forwarding
	 * the wrong address limit to access_ok under speculation.
	 */
	dsb(nsh);
	isb();

	/* On user-mode return, check fs is correct */
	set_thread_flag(TIF_FSCHECK);

	/*
	 * Enable/disable UAO so that copy_to_user() etc can access
	 * kernel memory with the unprivileged instructions.
	 */
#设置让非特权指令访问kernel的内存
	if (IS_ENABLED(CONFIG_ARM64_UAO) && fs == KERNEL_DS)
		asm(ALTERNATIVE("nop", SET_PSTATE_UAO(1), ARM64_HAS_UAO));
	else
		asm(ALTERNATIVE("nop", SET_PSTATE_UAO(0), ARM64_HAS_UAO,
				CONFIG_ARM64_UAO));
}
这里的UAO目前都是默认打开的,是armv8.2的新特性
config ARM64_UAO
	bool "Enable support for User Access Override (UAO)"
	default y
	help
	  User Access Override (UAO; part of the ARMv8.2 Extensions)
	  causes the 'unprivileged' variant of the load/store instructions to
	  be overridden to be privileged.

	  This option changes get_user() and friends to use the 'unprivileged'
	  variant of the load/store instructions. This ensures that user-space
	  really did have access to the supplied memory. When addr_limit is
	  set to kernel memory the UAO bit will be set, allowing privileged
	  access to kernel memory.

	  Choosing this option will cause copy_to_user() et al to use user-space
	  memory permissions.

	  The feature is detected at runtime, the kernel will use the
	  regular load/store instructions if the cpu does not implement the
	  feature.

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/83511819