windows - 受保护的共享内存

时间:2014-01-17 22:06:15

标签: c++ windows shared-memory readonly protected

我正在寻找在Windows平台上创建共享内存块的可能性,除了创建共享内存块的进程外,所有进程都有写保护。

详细说明我需要以下内容:

进程(1)必须创建共享内存块,并且应该能够修改缓冲区。 进程(2)应该能够打开并读取创建的共享内存块,但不能拥有修改内容的权限。出于安全/安全原因,这很重要。

目前我有一个使用CreateFileMapping()和MapViewOfFile()创建共享内存块的解决方案,然后MapViewOfFile()在进程(1)和(2)中具有读写权限,如:

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, highSize, lowSize, L"uniquename");
void* sharedMemory = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
// now we can modify sharedMemory...

这两行代码可以应用于两个进程,因为第一个进程创建共享内存块,第二个进程只是打开共享内存。 但是,显然第二个进程由于在创建内存块期间提供的访问值(PAGE_READWRITE和FILE_MAP_ALL_ACCESS)而具有写权限。

我需要使用访问值PAGE_READONLY和FILE_MAP_READ在进程(1)中创建共享内存块,但显然我不允许在进程(1)中初始化/设置/修改内存块,而不是无用的内存缓冲区。

据我所知,安全属性的定义无法解决问题,因为我的问题不依赖于用户或组。

我甚至会对在进程中创建共享内存块的解决方案感到满意(1)依赖于在创建共享内存块之前已知的内存内容(之后在进程(1)中不会被修改) )。

3 个答案:

答案 0 :(得分:2)

您是否相信流程#2才能使用FILE_MAP_READ?这将防止意外覆盖例如狂野指针破坏共享内存。

如果您正在尝试防止恶意覆盖,那么您需要使用操作系统提供的安全主体,并在具有较少凭据的不同会话中运行进程#2。如果进程#2在与进程#1相同的安全凭证下运行,那么它可以执行#1可以执行的任何操作进程(例如,通过将代码注入进程#1)。

(在Windows上,用户是安全主体,而进程则不是。用户不是唯一的限制级别,例如Vista中的用户访问控制以及稍后创建与管理员用户相对应的令牌,无论是否具有管理员组成员身份)

由于您说进程#1不需要继续写访问,只需要一次,您可以创建映射,将其映射为write,然后使用SetSecurityInfo调整ACL,以便将来的访问无法写入。 / p>

另一种可能性是映射磁盘文件,然后使用FILE_SHARE_READ(但不是FILE_SHARE_WRITE)从第一个进程打开它。

但这些都不会阻止进程#2强制进程#1进行更改。只使用单独的令牌可以防止强制。

答案 1 :(得分:1)

你没有解释为什么你不能在每种情况下都提供不同的参数,所以在你打开文件之前我会假设你不知道哪个进程是创建者。在这种情况下,您可能想尝试:

HANDLE h = OpenFileMapping(FILE_MAP_READ, /*args*/);
if (h) {
    v = MapViewOfFile(h, FILE_MAP_READ, 0, 0, 0);
} else {
    h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, highSize, lowSize, L"uniquename");
    if (!h)
        FirePhotonTorpedoes();
    v = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
}

答案 2 :(得分:0)

CreateFileMapping函数允许您为文件映射对象设置ACL。如果创建仅允许只读访问的ACL,则其他进程应该无法以读写访问权限打开文件映射对象。

通常,在创建对象时,您分配的权限不适用于您在创建期间获得的句柄。但是,我没有特别使用CreateFileMapping进行测试。

这只提供弱保护。恶意进程可能会更改文件映射对象的权限,或者将代码注入创建对象的进程中。