天天看點

繼續蹂躏linux

話說linux的核心空間不能通路使用者空間,這是真的嗎?前面說過很多次,沒有什麼是絕對不能的,一定要區厘清楚什麼是不允許什麼是不可能,使用者空間不能通路核心空間是硬體規定和實作的,但是反過來,核心空間不能通路使用者空間卻隻是linux的一種約定,一種規定或者多多少少有點設計上的約定,核心空間擁有至高無上的權力為何要限制它呢?其實不是限制而是這樣規定使得實作起來更加友善和有條理,仔細想想,核心空間被所有的程序共享,你讓核心通路使用者空間, 那麼通路誰的使用者空間呢?是以要想實作核心通路使用者空間,必須在通路時指明通路哪個程序的使用者空間,而且還會涉及缺頁處理的問題,畢竟核心通路的使用者空間對應的程序可能不是目前程序,之後的複雜性就不用多說了吧。另外的原因就是設計上的規定了,設計上有個“流”的概念,要想使設計靈活,子產品化,或者說低耦 合,那就得使對應的流單向化,就是所謂的單向依賴,tcp/ip模型和osi模型就是這麼設計的,上層使用下層的服務,下層絕對不依賴上層,就是不會“調 用”上層,在作業系統的設計中當然也是這樣,核心為使用者空間服務并且不依賴使用者空間,就是不調用使用者空間。 

事實上就真的不能調用使用者空間嗎?肯定不是的,就像核心不允許在中斷中睡眠,但是你真的在中斷處理函數裡面調用了個schedule并不會使得核心馬上崩 潰,隻是核心後面的行為變得不能保證了。我們還是用核心子產品來實作一個核心通路使用者空間的例子,通路使用者空間的資料在《char *和char數組的差別(深拷貝和淺拷貝的觀點)以及核心通路使用者空間》裡面已經說過了,現在要談的的是核心調用使用者空間的函數,這個了解起來要明白兩個 東西,一個是程式的text段,一個程式的棧,一個函 

數的執行關聯到了text段和棧,所謂text段其實也是一種資料,核心調用使用者空間的函數實際上就是通路了使用者空間的資料,核心從使用者空間的text段取到被調函數的指令,這就通路了使用者空間資料,然後執行的場所呢?當然是棧了,有函數調用就需要棧,可是這個棧不是那個棧,核心調用使用者空間的函數時所用的棧是核心棧,其實也是目前程序的目前棧。這就是說,一個函數執行要弄明白兩點,一是到哪裡 取指令(一般為text段,當然在緩沖區溢出攻擊中可能是棧),二是在哪裡執行(一般是 

棧)。是以核心調用使用者空間的函數就是到使用者空間的text段取指令,在核心棧執行,如此而已,還有一個問題,就是如何得到使用者空間的函數位址,當然可以通過特征掃,也可以硬指派,我這裡為了簡單采用了後者,先看看使用者空間程式:

void userfunc( int i )

{

 本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1273433

繼續閱讀