計算機系統的安全機制

有價值炮灰發表於2016-08-20

最近王寶強同志不幸遭遇了一場事故,可謂是賠了夫人又折兵. 男人們看到這個
新聞,然後轉頭看看自己的另一半,眼神也不禁若有所思. 遭遇背叛是每個人都不願遇到的,
那麼我們作為目光短淺的凡人,該如何事先做好安全措施呢?看看作業系統實現的安全機制,
也許能給大家一點啟發.

前言

我們每天使用的裝置中,執行著不同的作業系統,比如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模式同樣也
包含了一些新的處理器指令.

後記

作業系統的分級保護, 對使用者來說是一個非常有效的安全保障, 也說明了"能力越大,責任越大"的道理,
每個人都要管理好自己的安全邊界, 在遭遇到不測時可以把損失降低到最小. 只可惜在日常中見過太多
人把許可權當作兒戲,放任惡意軟體進駐核心,不過那都是後話了.

部落格地址:

歡迎交流,文章轉載請註明出處.

相關文章