最近王寶強同志不幸遭遇了一場事故,可謂是賠了夫人又折兵. 男人們看到這個
新聞,然后轉頭看看自己的另一半,眼神也不禁若有所思. 遭遇背叛是每個人都不願遇到的,
那么我們作為目光短淺的凡人,該如何事先做好安全措施呢?看看操作系統實現的安全機制,
也許能給大家一點啟發.
前言
我們每天使用的設備中,運行着不同的操作系統,比如windows,android,ios等.每個操作系統里
又運行着不同的程序,因此每個CPU每秒執行的指令數量有上億條.其中不可避免地會有危險的指令,
比如任意內存訪問等操作,如果操作系統或者CPU.沒有相關的限制,那不免會經常崩潰.
為了解決這個問題,減少致命錯誤的發生幾率,於是工程師們引進了一種分級的保護機制.
Protection Ring
這個保護機制,就是一種權限分級制度,學名為分級保護域(Hierarchical Protection Domains),
又叫保護環(Protection Ring).即我們經常聽到的Ring0/Ring3.分級保護域是一種用來在發生故障時
保護數據和功能,提升容錯度,避免惡意操作,提升計算機安全的設計方式.這是一種與
能力基礎安全(capability-based security)完全相反的方式.
還是以寶強同志為例子, 想要不被傷害,不被欺騙,最好的辦法是什么?就是不要相信任何人.
也許有人覺得這種觀點極端了,但我不是說別人都對你圖謀不軌,親人朋友當然不太可能會對你有惡意,
但是他們有時候也只是沒有辨別是非的能力, 說白了他們本身也是被害者. 如果感情用事
而去盲目相信對方, 最后損失擴大反而對對方的傷害更大.
在計算機系統中也是如此. 有時候用戶根本就不知道自己在干什么, 也就是說不是誰都有
基礎能力的. 因此最好的辦法就是分級, 如下圖所示:
這是x86保護模式下的特權級別實例. 其中Ring3為用戶環(用戶態), Ring2-Ring1為驅動環,
Ring0為內核環(內核態),Ring0有最高的權限, Ring3的權限最低. 操作系統(內核)工作在Ring0層,
可以訪問所有層的數據; 而一些和硬件外設相關的程序如網卡,聲卡驅動等就工作在Ring1和
Ring2層; 用戶一般的應用程序則工作在Ring3層. 這樣分級的好處是確保進程不會彼此之間對
系統重要組件產生影響.保護環對工作在環內的進程能夠做什么,能夠執行什么命令做出了嚴格的定義.
在內環執行的進程比在外環執行的進程有更高的權限,內核只允許最可信的組件和進程在其中執行.
外環的程序想要直接執行特權指令時,操作系統會將其阻止,並且返回諸如"非法指令"的錯誤信息.
當然, 在安全和方便間有時候也需要作出取舍,為了在必要的時候給用戶態能夠執行高級指令,
內核提供了一系列接口來提供給用戶, 這些接口也被稱為系統服務調用.
實現
一開始的時候, 保護環機制是用純軟件來實現的, 操作系統通過軟件來捕獲Rings的轉換.
后來大部分的CPU都實現了保護環架構, 在指令集中提供指令或者硬件接口來進行Rings的
轉換, 如果在低權限模式執行了特權指令, 會觸發處理器的軟中斷, 從而使CPU不至於跑飛.
硬件上不同的CPU架構可能實現的保護環數量不同,但至少都會有兩個. 操作系統在此基礎上
一般只實現2個Ring級別(如Windows和Linux), 即Ring0和Ring3, 俗稱內核態和用戶態.
有的操作系統實現了3個Ring級別,如OS/2等,不過早就退出歷史舞台了.
值得一提的是,有的人把內核態和用戶態叫作內核空間和用戶空間. 但后者其實是虛擬內存的概念,
前者是基於硬件的保護, 不可同一而論. 不過其出發點是類似的, 在Linux下, 內核將地址空間(假設為4G)
分為兩部分, 高字節段(假設為1G)供內核使用,稱為內核空間, 低字節段(假設為3G)供各個進程使用,
稱為用戶空間. 從結果上來看, 每個進程都有3G的私人空間+1G的共享空間(通過系統調用進入內核空間).
這種划分是為了內存訪問保護的要求.
弊端
CPU對用戶態和內核態的分離對我們操作系統的使用者來說是相對透明的, 也帶來了不可估量的好處,
如果沒有保護環, 那我們平時遇到程序崩潰的時候, 就不是Ctrl+Alt+Del結束進程或者kill -9 pid那么
簡單了, 而是遭遇系統完全死機或者行為持續性異常. 但是,凡事各有利弊, 用戶態雖然安全,但也是
需要代價的. 要記住, 用戶態和內核態的切換開銷非常昂貴. 這也是為什么軟件拋出異常如此
之慢,因為異常意味着內核態的躍遷. 雖然說現在CPU的性能已經非常好,也不需要對那么點性能損失
較真,但在某些特殊場景下,模式的切換往往造成了性能的瓶頸.
虛擬化與Ring-1
Ring0-Ring3關於權限分級, 而Ring-1則主要關於虛擬化. 在X86仿真剛被提出來的時候,存在着一個
重大的障礙, 即宿主操作系統(host)和虛擬的操作系統(guest)都想要Ring0的訪問權限,但這是不被
允許的. 於是為了解決這個問題,人們提出了幾種方案. 其中一個方案是guest操作系統可以向虛擬機
管理器請求這些需要ring0權限的操作;另一種調用仿真的方案是由虛擬機管理器來虛擬一套指定的
硬件和ring0指令,然后捕捉guest操作系統的調用行為再代替其進行真正的ring0操作.
這些技術在調用操作方面付出了額外的開銷,對性能也造成不小的影響. 為了減輕這種情況,人們提出
改進傳統的保護環結構的想法,從而增加一個比Ring0更高權限的層級,稱為Ring-1. 在Ring-1模式下,
可以有能力對指令進行仿真, 從而每個虛擬操作系統都能運行在Ring0之下,並且不影響其他的虛擬
系統(有意或無意的). 要支持這種需求則需要CPU在硬件結構上作出相應的改變. Ring-1模式同樣也
包含了一些新的處理器指令.
后記
操作系統的分級保護, 對用戶來說是一個非常有效的安全保障, 也說明了"能力越大,責任越大"的道理,
每個人都要管理好自己的安全邊界, 在遭遇到不測時可以把損失降低到最小. 只可惜在日常中見過太多
人把權限當作兒戲,放任惡意軟件進駐內核,不過那都是后話了.
博客地址:
歡迎交流,文章轉載請注明出處.