我正在開發一個使用共享記憶體的應用程式shm_open()。它mmap()從內部的檔案執行,/dev/shm并基于生產者/消費者方法。
是否有任何機制可以保護我的共享記憶體并只能由該應用程式訪問?我知道可以使用加密,但是 linux(或編程語言)是否提供任何服務以使該檔案只能由我的應用程式訪問?
uj5u.com熱心網友回復:
如果使用fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0);,則任何其他行程都無法打開共享記憶體物件(無需先更改訪問模式)。如果成功( ),并且您立即通過成功( )fd != -1取消鏈接物件,則只有可以訪問當前行程本身的行程才能訪問該物件。int rc = shm_unlink(name);rc == 0
當另一個具有足夠權限的行程可能已更改模式并打開物件時,這兩個操作之間有一個小的時間視窗。要進行檢查,請使用fcntl(fd, F_SETLEASE, F_WRLCK)獲取物件的寫租約。只有當這是唯一可以訪問該物件的行程時,它才會成功。
讓應用程式的第一個實體系結到先前同意的 Unix 域流套接字,命名或抽象,并在其上偵聽傳入連接。(出于安全原因,重要的是fcntl(sockfd, F_SETFD, FD_CLOEXEC)要避免將套接字泄漏給子行程,以防它 exec()sa 新的二進制檔案。)
如果socket已經被系結,則系結失敗;所以連接到那個套接字。當第一個實體接受新連接,或者第二個實體連接到 i 時,兩者都必須使用int rc = getsockopt(connfd, SOL_SOCKET, SO_PEERCRED, &creds, &credslen);with struct ucred creds; socklen_t credslen = sizeof creds;,以獲取對方的憑據。
然后,您可以檢查uid另一端的 和 是否匹配getuid(),geteuid()并使用例如stat()路徑"/proc/PID/exe"(另一端的在哪里)PID與. 如果他們這樣做,雙方都在執行相同的二進制檔案。(請注意,您還可以使用 POSIX 實時信號,通過在它們之間傳遞一個資料標記(of 、void 指標或/在 Linux 上恰好匹配/ )。)這很有用,例如,如果一個人想通知另一個人他們即將退出,另一個應該系結并監聽 Unix 域流套接字上的傳入連接。)pid"/proc/self/exe"sigqueue()intuintptr_tintptr_tunsigned longlong
然后,初始行程可以使用輔助訊息將共享物件描述的副本(通過描述符fd)傳遞給第二個行程,例如共享物件的實際大小作為資料(為此推薦 a)。如果要傳遞其他內容,請使用結構。SCM_RIGHTS size_t
第二個行程接收的第一個(通常但不一定是唯一的)訊息將包含輔助資料,其中包含參考共享物件的新檔案描述符。請注意,因為這是一個 Unix 域流套接字,所以不保留訊息邊界,如果沒有完整的資料負載,則需要使用回圈來讀取其余資料。
然后雙方都可以關閉 Unix 域套接字。然后第二方可以mmap()共享物件。
如果只有這對共享資料的行程,那么雙方都可以關閉描述符,使得除了超級用戶或內核之外的任何人都無法訪問共享描述符。只要映射存在,內核就會保留一個內部參考;它相當于行程的描述符仍然打開,只是行程本身不能再訪問或共享描述符,只能訪問或共享共享記憶體本身。
因為共享物件已經被取消鏈接,所以不需要清理。一旦具有打開描述符或現有 mmap 的最后一個行程將其關閉、取消映射或退出,共享物件就會消失。
Linux 實作的 Unix 安全模型在以相同方式運行的行程之間沒有嚴格的界限uid。特別是,他們可以檢查彼此/proc/PID/的偽目錄,包括它們在 中列出的打開檔案描述符/proc/PID/fd/。
因此,對安全敏感的應用程式通常以專用用戶的身份運行。即使當第二方是作為人類用戶運行的行程,而第一方作為專用應用程式 uid 時,上述方案也能很好地作業。如果你使用命名的Unix域流套接字,你確實需要確保它的訪問模式是合適的(你可以在系結到套接字后使用chmod(),,chgrp()等來改變命名的Unix域流套接字訪問模式)。摘要 Unix 域流套接字沒有檔案系統可見節點,任何行程都可以連接到這樣一個系結的套接字。
當應用程式(作為自己的專用 uid 運行)和代理(作為用戶 uid 運行)之間涉及權限邊界時,確保雙方都是他們在整個交換中聲稱的身份是很重要的。憑證僅在該時間點有效,已知的攻擊方法是讓有效代理在連接到套接字后立即執行惡意二進制檔案,以便對方仍然看到原始憑證,但接下來的通信是控制一個邪惡的程序。為避免這種情況,請確保套接字描述符未在 exec 之間共享(使用CLOEXEC描述符標志),并可選擇多次檢查對等憑據,例如最初和最后。
為什么這“復雜”?因為必須加入適當的安全性,所以不能事后將其添加到頂部,或在無形中為您處理:它必須是方法的一部分。方法的改變必須反映在安全實作中,否則你就沒有安全性。
在現實生活中,在你實作了這個(對于相同的可執行二進制檔案,以及特權服務或應用程式和用戶代理檔案)之后,你會發現它并不像聽起來那么復雜:每個step 有其目的,如果方法發生變化,可以對其進行調整。特別是,它根本沒有多少 C 代碼。如果一個人想要或需要“更簡單的東西”,那么他只需要選擇安全敏感代碼以外的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/515530.html
上一篇:隨機訪問在線托管的docker-app的人可以訪問源代碼嗎?
下一篇:如何從Wildfly獲取密碼
