2012-08-17 47 views
5

我正在編寫可訪問特定進程內存的內核模塊。我已經做了一些用戶存儲空間的匿名映射與do_mmap()從內核模塊更改用戶空間內存保護標誌

#define MAP_FLAGS (MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS) 

prot = PROT_WRITE; 
retval = do_mmap(NULL, vaddr, vsize, prot, MAP_FLAGS, 0); 

vaddrvsize被先前設置,呼叫成功。在我從內核模塊(通過copy_to_user)寫入該內存塊後,我想要刪除它的PROT_WRITE權限(就像我在普通用戶空間中使用mprotect)。我似乎無法找到一個允許這個功能。

我試圖解開映射區域並用正確的保護重新映射它,但是將內存塊清零,擦除了我剛寫入的所有數據;設置MAP_UNINITIALIZED可能會解決這個問題,但是,從手冊頁:

MAP_UNINITIALIZED(因爲Linux 2.6.33)

不清除匿名頁面。此標誌旨在提高嵌入式設備的性能。只有在內核配置了 CONFIG_MMAP_ALLOW_UNINITIALIZED選項時,才能使用該標誌。由於安全隱患,該選項 通常僅在嵌入式設備(即其中一個具有完整的用戶內存內容控制權的設備)上啓用。

所以,雖然這可能做我想要的,它不會很便攜。有沒有一個標準的方法來完成我所建議的?

+0

爲什麼哦你爲什麼要在你的內核模塊中做所有的事情?有了一個明確定義的API,沒有理由不能由用戶空間進程本身完成。 – mpe 2012-08-17 12:13:10

+0

@mpe我在用戶空間中無法完成的原因是我正在編寫的模塊是一個進程加載器;我對用戶空間代碼沒有任何影響力。 – nosuchthingasstars 2012-08-17 12:31:40

+0

流程加載器是什麼意思?你的意思是一個binfmt處理程序? – mpe 2012-08-17 15:33:27

回答

1

一些調查研究後,我發現了一個名爲get_user_pages()功能(我發現最好的文檔here)返回的,可以被映射到內核空間kmap()並寫入到從用戶空間在一個給定的地址頁面列表方式(在我的情況下,使用kernel_read())。這可以用作copy_to_user()的替代品,因爲它允許在檢索到的頁面上強制寫入權限。唯一的缺點是你必須一頁接一頁地寫,而不是一頁一頁,但它確實解決了我在我的問題中描述的問題。

0

在用戶空間中有一個系統調用mprotect,它可以修改現有映射上的保護標誌。您可能需要從該系統調用的實現中繼續,或者直接從您的代碼中直接調用它。見mm/protect.c

相關問題