kernel space 中呼叫系統呼叫對地址空間檢查
阿新 • • 發佈:2018-11-23
在核心中呼叫系統呼叫,需要使用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.