2016-01-12 62 views
5

我需要創建包含一些祕密數據的共享內存段。我使用shmgetshmat函數來訪問具有權限的段。我只想與分叉進程共享這段內存。我試圖創建另一個試圖訪問該段的應用程序,但它不成功,所以它看起來像我想要的那樣工作。拒絕從非分叉進程訪問共享內存

但是,當我運行再次創建該段的應用程序時,它可以訪問該段。這怎麼可能?將祕密數據存儲到共享內存是一個好主意嗎?

回答

4

共享seg不屬於一個進程,它屬於一個用戶。有效的設置0600只允許該用戶使用RW(和root),但其他任何正在運行的進程都將具有相同的訪問權限。

創建一個特定的用戶,僅用於此目的「使用」(登錄)。

在共享內存段中有祕密數據是一個好主意嗎?

將段看作文件 - 可能不太容易訪問(需要了解IPC) - 除非在系統關閉時消失。

將祕密存儲在文件中是一個好主意嗎?如果數據是明文,也許不會。

在文件或共享mem段中,數據加密是一種改進。

請參閱this page瞭解如何控制shmem段的詳細說明。


OTOH如果你需要的只是一個過程與她的孩子交換信息,見 processes piping。在這種情況下,祕密數據存儲在進程堆/堆棧內存中,並且由同一用戶擁有的外部進程更難以達到。但用戶「擁有」該進程也可能會讀取進程內存(例如通過核心轉儲)並搜索祕密數據。不那麼容易,但仍然可能。

請注意,在這種情況下,如果祕密數據在執行fork()之前在父進程中可用,則子代會自動繼承它。

不管怎樣,想想加密。

+0

一般,加密就可以了..但我在第一次已經加密的數據(從文件),該文件是非常大的。 。有多個進程想要讀取乾淨的數據..所以我想解密數據到共享內存.. –

6

您可以通過在父進程中提供MAP_SHAREDMAP_ANONYMOUS標誌來共享和匿名內存區域mmap()。該內存將僅供該進程及其子進程訪問。由於內存段是匿名的,沒有其他進程將能夠引用它,更別說訪問/圖吧:

void *shared_mem = mmap(NULL, n_bytes, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); 

父進程應該創建一個使用mmap()共享內存段。該內存段由fork()創建的任何子進程繼承。子進程可以簡單地使用shared_mem指針從父母繼承來指代內存段:

#include <sys/mman.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main() 
{ 
    void *shared_mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); 

    pid_t pid = fork(); 
    if (pid > 0) { 
     // parent 
     // use shared_mem here 

    } else if (pid == 0) { 
     // child 
     // use shared_mem here 

    } else { 
     // error 
    } 
    return 0; 
} 
+0

我試過這個,但可能我做了錯誤的事情。第一個進程在其開始後立即創建一個使用'mmap'的共享內存段,並將指針的值保存到由'shmget'和'shmat'訪問的共享內存中。下一個過程(從第一個分叉)讀取「mmap」指針,但是當我嘗試訪問它時,它會導致段錯誤: - /應用程序可能在'fork'後調用'execve'(我不知道該應用程序深),因此我無法訪問共享內存。 –

+0

不,你根本不必使用'shmget'和'shmat'。我會更新我的答案。 –

+0

我知道,你想告訴我什麼,但在我的情況是'main'函數運行兩次。它看起來像'fork'被稱爲'execve'後運行與修改參數相同的應用程序。所以在新的過程中,我無法讀取'shared_mem'變量。這就是爲什麼我將指針保存到共享內存中的原因。 –