成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux內核如何判斷地址是否位于用戶空間?

系統 Linux
有粉絲提問Linux內核如何判斷地址是否位于用戶空間?本篇就這一問題給大家詳細介紹相關解決方案。

[[388929]]

一、 問題描述

access_ok函數是什么原理?

 

 

 

問題

 

二、問題分析

我們在內核空間和用戶空間進行數據拷貝的時候必須判斷用戶空間地址是否合法。主要通過偶函數access_ok來判斷。

1. Linux用戶空間與內核地址空間

Linux 操作系統和驅動程序運行在內核空間,應用程序運行在用戶空間,兩者不能簡單地使用指針傳遞數據,因為Linux使用的虛擬內存機制,用戶空間的數據可能被換出,當內核空間使用用戶空間指針時,對應的數據可能不在內存中。

通常32位Linux內核地址空間劃分0~3G為用戶空間,3~4G為內核空間。注意這里是32位內核地址空間劃分,64位內核地址空間劃分是不同的。

 

 

 

 

  • 進程尋址空間0~4G
  • 進程在用戶態只能訪問0~3G,只有進入內核態才能訪問3G~4G
  • 進程通過系統調用進入內核態
  • 每個進程虛擬空間的3G~4G部分是相同的
  • 進程從用戶態進入內核態不會引起CR3的改變但會引起堆棧的改變

2. access_ok詳解

原型:

 

  1. access_ok ( type,addr,size); 

功能:

  • access_ok — 檢查用戶空間指針是否有效 注意,根據體系結構的不同,這個函數可能只是檢查指針是否在用戶空間范圍內,在調用這個函數之后,內存訪問函數可能仍然返回 -EFAULT

參數說明:

  • typeType of access: VERIFY_READ or VERIFY_WRITE. 請注意,VERIFY_WRITE是VERIFY_READ的超集——如果寫入一個塊是安全的,那么從它讀取總是安全的。addr要檢查的塊的開始的用戶空間指針size要檢查的塊的大小

返回值:

  • 此函數檢查用戶空間中的內存塊是否可用。如果可用,則返回真(非0值),否則返回假 (0) 。

2. 源碼分析

 

  1. #define access_ok(type, addr, size) (__range_ok(addr, size) == 0) 

 

  1. /* We use 33-bit arithmetic here... */ 
  2. #define __range_ok(addr, size) ({ \ 
  3.  unsigned long flag, roksum; \ 
  4.  __chk_user_ptr(addr); \ 
  5.  __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \ 
  6.   : "=&r" (flag), "=&r" (roksum) \ 
  7.   : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ 
  8.   : "cc"); \ 
  9.  flag; }) 

 

  1. static inline void __chk_user_ptr(const volatile void *p, size_t size
  2.  assert(p >= __user_addr_min && p + size <= __user_addr_max); 

其中__range_ok詳解如下:參數對應:

 

  1. flag   --------  %0 
  2. roksum --------  %1 
  3. addr   --------  %2 
  4. size   --------  %3 

匯編指令詳解

 

  1. adds %1, %2, %3 

等價于:

 

  1. rosum = addr + size 

這個操作會影響狀態位(目的是影響是進位標志C)。

以下的兩個指令都帶有條件CC,也就是當C=0的時候才執行;如果上面的加法指令進位了(C=1),則以下的指令都不執行,flag就為初始值current_thread_info()->addr_limit(非0),并返回。如果沒有進位(C=0),就執行下面的指令:

 

  1. sbcccs %1, %1, %0 

該指令等價于

 

  1. rosum = rosum - flag - 1 

也就是(addr + size) - (current_thread_info()->addr_limit) - 1,操作影響符號位。.

如果(addr + size) >= (current_thread_info()->addr_limit) - 1,則C=1 如果(addr + size) < (current_thread_info()->addr_limit) - 1,則C=0 當C=0的時候執行以下指令,否則跳過(flag非零)。

 

  1. movcc %0, #0 

等價于

 

  1. flag = 0,給flag賦值0。 

綜上所述:__range_ok宏等價于:

 

  1. 如果(addr + size) >= (current_thread_info()->addr_limit) - 1,返回非零值 
  2. 如果(addr + size) < (current_thread_info()->addr_limit),返回零 

而access_ok就是檢驗將要操作的用戶空間的地址范圍是否在當前進程的用戶地址空間限制中。這個宏的功能很簡單,完全可以用C實現,不是必須使用匯編。 由于這兩個函數使用頻繁,就使用匯編來實現部分功能來增加效率。

3. 使用實例

我們在內核拷貝數據到用戶空間或者從用戶空間拷貝數據到內核空間,都需要判斷用戶空間地址是否在用戶空間。

 

 

  1. static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) 
  2.  if (access_ok(VERIFY_READ, from, n)) 
  3.   n = __copy_from_user(tofrom, n); 
  4.  else /* security hole - plug it */ 
  5.   memset(to, 0, n); 
  6.  return n; 
  7.  
  8. static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) 
  9.  if (access_ok(VERIFY_WRITE, to, n)) 
  10.   n = __copy_to_user(tofrom, n); 
  11.  return n; 

 

責任編輯:姜華 來源: 一口Linux
相關推薦

2021-01-08 05:59:39

Linux應用程序Linux系統

2017-08-24 11:00:56

Linux用戶空間內核空間

2010-05-13 09:45:26

Linux地址空間

2021-01-14 09:37:20

內核空間用戶

2022-02-18 00:15:58

Linux指令CPU

2016-08-10 12:52:31

2009-12-07 09:31:23

Linux系統調用表地址

2013-12-06 10:20:21

2020-11-12 06:03:54

IP IPv4IPv6

2018-05-18 09:07:43

Linux內核內存

2012-05-21 17:02:19

Linux審計

2010-03-03 14:17:02

Linux內核

2019-07-10 12:40:29

Linux虛擬地址空間物理地址空間

2009-09-07 09:20:34

2017-12-06 19:00:53

2012-05-03 08:27:20

Linux進程

2020-12-09 05:25:23

Linux內存進程

2010-12-29 10:08:38

Linux load

2019-01-02 16:12:17

Linux系統 vmstat

2012-05-25 10:00:46

Ubuntu 12.0Linux
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线观看视频一区 | 亚洲精品中文字幕av | 小早川怜子xxxxaⅴ在线 | 日韩播放 | 精品国产不卡一区二区三区 | 日韩视频一区二区三区 | 亚洲电影中文字幕 | 亚洲精品一二三区 | 欧美精品一区二区三区在线 | 91精品国产91久久久久久丝袜 | 少妇诱惑av| 欧美日韩亚洲国产综合 | 91免费在线视频 | 国产精品久久久久久久久免费丝袜 | 欧美一级黄视频 | 久久久这里都是精品 | 偷拍自拍网址 | 日韩中文在线视频 | 亚洲最大的成人网 | 最新中文字幕第一页视频 | 欧美激情国产日韩精品一区18 | 国产精品伦理一区 | 成人精品鲁一区一区二区 | 亚洲一区二区av | 欧美在线视频一区二区 | 波霸ol一区二区 | 天天操夜夜操免费视频 | 久久精品久久久 | 久草新在线| 亚洲精品欧洲 | 久久国产欧美一区二区三区精品 | 欧美一区二区三区在线观看视频 | 午夜网| 国产乱人伦精品一区二区 | 日韩欧美视频免费在线观看 | www.97zyz.com | 欧美亚洲国产日韩 | 国产一区二区三区四区三区四 | 国产精品不卡视频 | 国产精品99久久久久久久久久久久 | 亚洲精品日韩在线 |