mprotect機(jī)制
Linux系統(tǒng)提供了一個(gè)系統(tǒng)調(diào)用接口mprotect接口,通過(guò)該接口可以在編寫(xiě)Linux程序時(shí)給mmap申請(qǐng)到的內(nèi)存設(shè)置權(quán)限,從而允許或限制對(duì)該部分內(nèi)存的讀寫(xiě),執(zhí)行。
函數(shù)原型:
int mprotect(constvoid*start,size_tlen,int prot);
說(shuō)明:自地址start開(kāi)始,保護(hù)長(zhǎng)度為len的內(nèi)存空間。其中prot參數(shù)可以有如下取值:

函數(shù)返回取值:
成功返回0,失敗返回-1,并且設(shè)置errno,errno可能有如下取值:

Pkeys保護(hù)機(jī)制
Pkeys 的工作原理是:在每個(gè)頁(yè)表中,將 4 個(gè)先前保留的位專門(mén)用于一個(gè)“保護(hù)鍵”,從而提供 16 個(gè)可能的鍵。
每個(gè)鍵的保護(hù)由一個(gè) per-CPU 用戶可訪問(wèn)寄存器(PKRU) 定義。每個(gè) PKRU 都是一個(gè) 32 位寄存器,為 16 個(gè)鍵中的每個(gè)鍵存儲(chǔ)兩位(訪問(wèn)禁用和寫(xiě)入禁用)。
作為 CPU 寄存器,PKRU 本質(zhì)上是線程局部的,可能使每個(gè)線程擁有與其他所有線程不同的保護(hù)集。
Linux提供了3個(gè)對(duì)應(yīng)的系統(tǒng)調(diào)用用于pkeys內(nèi)存保護(hù)機(jī)制

基本用法:
1:在使用之前先調(diào)用pkey_alloc分配一個(gè)key。
2:然后調(diào)用pkey_mprotect
3:要修改該部分內(nèi)存訪問(wèn)權(quán)限時(shí),調(diào)用pkey_set
如下是一樣例代碼:

內(nèi)存保護(hù)生效后,使用過(guò)程中違反了對(duì)應(yīng)權(quán)限后,對(duì)于通過(guò)mprotect做保護(hù)的應(yīng)用,程序會(huì)報(bào)SEGV_ACCERR錯(cuò)誤,對(duì)于使用pkeys做保護(hù)的應(yīng)用,程序報(bào)錯(cuò)SEGV_PKERR。