2016-01-12 37 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'变量。这就是为什么我将指针保存到共享内存中的原因。 –