CPU的底線:為什么只有操作系統(tǒng)才能執(zhí)行這些操作?
你正在編寫一個普通的應用程序,突發(fā)奇想,想要直接控制硬盤讀寫、修改其他程序的內存空間,甚至直接關閉整個計算機系統(tǒng)。如果你嘗試這樣做,結果會怎樣?
答案很簡單,在現(xiàn)代操作系統(tǒng)上,你的程序不但不能接管計算機反而會被反殺掉。
有一系列操作是絕對不允許在用戶態(tài)執(zhí)行的。
直接內存管理
內存是計算機系統(tǒng)最基礎的資源,必須由操作系統(tǒng)統(tǒng)一管理。內核通過CPU提供的虛擬內存技術為每個進程創(chuàng)建獨立的虛擬地址空間,實現(xiàn)進程間的內存隔離,這其中最核心的就是頁表。
圖片
如果用戶程序能夠隨意修改頁表,將導致災難性后果,因為這意味著:
- 進程可能訪問其他進程的私有內存,造成數(shù)據泄露或損壞
- 進程可能修改內核內存,破壞系統(tǒng)核心數(shù)據結構
- 內存保護機制失效,導致系統(tǒng)不穩(wěn)定或完全崩潰
例如,如果一個程序能夠修改CR3寄存器,它就可以切換到任意進程的地址空間,讀取或修改其他程序的數(shù)據,這將完全破壞系統(tǒng)的安全邊界。
特權指令
有些指令可以直接控制CPU的核心行為,包括但不限于:
- 開關中斷指令(CLI/STI)
- 修改控制寄存器(CR0、CR2、CR4等)
- 執(zhí)行I/O指令(IN/OUT)
如果我們寫的程序直接關閉中斷(CLI),那么這將導致系統(tǒng)無法響應外部事件,包括定時器中斷,從而阻止操作系統(tǒng)重新獲得控制權,這意味著我們寫的while循環(huán)將會真正的獨占一個CPU核心。
圖片
如果我們寫的程序可以修改控制寄存器,那么就可以直接禁用內存保護或更改CPU的基本運行模式。
直接硬件讀寫
有些操作可以直接控制硬件的讀寫,這包括:
- 使用IN/OUT指令直接讀寫I/O端口
- 訪問內存映射I/O(MMIO)區(qū)域
硬件設備是系統(tǒng)共享資源,需要協(xié)調訪問以避免沖突,不正確的硬件操作可能導致設備故障或數(shù)據損壞,多個程序同時訪問同一設備會導致操作沖突和數(shù)據損壞,而不正確的設備命令序列可能導致硬件故障。
例如,如果用戶程序可以直接訪問硬盤控制器,它可以繞過文件系統(tǒng)和權限檢查,讀取或修改任何磁盤扇區(qū),包括其他用戶的私有文件或系統(tǒng)關鍵數(shù)據。
內核數(shù)據結構
內核維護著大量復雜而關鍵的數(shù)據結構,這些數(shù)據結構共同構成了系統(tǒng)運行的大腦,對系統(tǒng)的正常運行至關重要。因此對這些數(shù)據結構的訪問和修改必須嚴格限制在內核態(tài)下進行。
圖片
(PS,這是人能看懂的東西?)
在Linux等現(xiàn)代操作系統(tǒng)中,內核數(shù)據結構包括進程控制塊(在Linux中稱為task_struct)、文件描述符表、中斷向量表、頁表等。如果允許普通用戶程序隨意訪問和修改這些數(shù)據結構,將會帶來災難性的后果。
以進程控制塊為例,它存儲了進程的所有關鍵信息,包括進程ID、用戶ID、權限位圖、資源限制和調度參數(shù)等。如果一個惡意程序能夠修改自己的進程控制塊,它可以輕松地將自己的有效用戶ID改為0(即root或管理員),立即獲得系統(tǒng)的最高權限,從而繞過所有安全檢查,訪問任何文件,執(zhí)行任何操作。
CPU的權限控制
因為我們可以看到,實際上CPU執(zhí)行的指令可以分為兩類,一類就是以上列舉的操作(操作系統(tǒng)的職責范疇),再一類就是我們寫的程序(被編譯后生成的指令),CPU在執(zhí)行這兩類指令時需要具有不同的權限等級。
現(xiàn)代CPU(如x86架構)通常實現(xiàn)了多個特權級別,從Ring 0(最高權限)到Ring 3(最低權限)。雖然有四個級別,但大多數(shù)操作系統(tǒng)只使用其中的兩個:
- Ring 0(內核態(tài)):操作系統(tǒng)內核運行的特權級別
- Ring 3(用戶態(tài)):普通應用程序運行的特權級別
圖片
只有當CPU位于Ring0也就是內核態(tài)時才可以執(zhí)行我們剛才列舉的這些操作,否則會觸發(fā)異常,這會進一步觸發(fā)操作系統(tǒng)的運行,操作系統(tǒng)運行起來后會終止掉有問題的進程。
因此如果我們的代碼想要執(zhí)行上述操作的話就只能讓操作系統(tǒng)替代我們去執(zhí)行,這通過系統(tǒng)調用來實現(xiàn)。
CPU的這種特權級別隔離機制是計算機系統(tǒng)安全穩(wěn)定運行的基石設計之一,這是現(xiàn)代計算機能夠同時運行數(shù)十甚至數(shù)百個程序而保持穩(wěn)定的關鍵所在。