2010-11-09 76 views
5

根據x86和ppc上的linux設計,4g虛擬地址空間被劃分爲3:1。 用戶虛擬地址是3g。爲什麼需要copy_to/from_user?

現在,如果用戶應用程序做了一個ioctl傳遞指針到緩衝區,內核模塊,可以直接做一個memcpy,我試過,它的工作。 =>爲什麼我們需要一個copy_to/copy_from用戶。

注意:如果頁面被換出,內核頁面錯誤處理程序會將其返回,並且它對內核模塊不可見。

需要你的想法...評論

回答

9

有幾個很好的理由認爲copy_to_user/copy_from_user是正確的功能,使用方法:

  • 在某些架構上簡單memcpy()工作,因此使用這些功能允許您的代碼在那裏工作。我相信即使選擇HIGHMEM配置選項的x86也在這艘船上。

  • 這些功能做一個access_ok()檢查,以確保真正引用的用戶空間地址是真實的用戶空間地址。如果您只是執行memcpy(),則ioctl()的調用方可以提供與內核地址重疊的地址範圍,這是一個安全漏洞。

  • 但是,主要的原因是要正確處理不良的用戶地址。如果您僅使用memcpy(),則未處理的故障將導致內核哎呀。用戶訪問功能使用"fixup" mechanism,它允許處理故障(讀或寫很短,在這種情況下,通常EFAULT返回給用戶空間)。

+0

好的,所以主要原因是處理**壞**地址。 – mSO 2010-11-09 10:22:50

+0

,如果地址有效(比如說最好的情況,沒有人做任何惡作劇),memcpy應該可以工作。 – mSO 2010-11-09 10:24:04

+0

@Manish:這不一定是「惡作劇」,它可能只是用戶空間中一個普通的舊bug - 這些bug應該由內核優雅地處理。而'memcpy()'只能在一些體系結構上運行。 – caf 2010-11-09 21:57:39

0

你很幸運,它的工作。

用戶空間和內核空間在完全不同的地址空間中運行。當您copy_to_user時,內核會將用戶空間虛擬地址轉換爲真實物理地址並將數據複製到那裏。反過來也會發生類似的過程。

如果您的硬件支持分散/聚集DMA,則可以直接跳過複製到/從步驟直接複製。在這裏,您可以將連續的虛擬內存塊映射到一系列物理頁面中,然後使用該信息直接將DMA寫入用戶空間。當然,如果任何虛擬地址空間當前沒有映射到物理內存(認爲交換或文件支持的mmaps),這會產生複雜性。

+0

3g:1g拆分應該照顧到這一點。 AFAIK內核不需要將va轉換成pa進行復制。 – mSO 2010-11-09 10:25:09