1. 程式人生 > >kernel space 中呼叫系統呼叫對地址空間檢查

kernel space 中呼叫系統呼叫對地址空間檢查

在核心中呼叫系統呼叫,需要使用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.