尝试使用 CreateFileMapping 和自定义 DACL 创建只读共享内存区域在 OpenFileMapping 中失败

Attempting to create a read only shared memory area with CreateFileMapping and custom DACL fails in OpenFileMapping

我有一个 client/server 本地进程,我希望在公开的 只读 共享内存区域中为其提供一些内容。我能够在服务器端成功创建安全描述符和共享内存区域,但是当我尝试访问客户端的共享内存区域时,它失败并显示 ACCESS_DENIED (5) unless 除了读取 (GR) 之外,安全描述符还向交互式用户 (GW) 授予写入访问权限。我试图避免向交互式用户授予写访问权限,以防止恶意进程破坏共享内存区域。

服务器端设计为 运行 作为 windows 服务并使用全局部分,但我发现为了解决此问题,它是什么并不重要运行宁为.

服务器端:

// Error handling removed for brevity
SECURITY_ATTRIBUTES attributes = { 0 };
ZeroMemory(&attributes, sizeof(attributes));
attributes.nLength = sizeof(attributes);
ConvertStringSecurityDescriptorToSecurityDescriptor(
    L"D:P(D;;GA;;;BG)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;IU)",
    SDDL_REVISION_1, &attributes.lpSecurityDescriptor, NULL);

DWORD cbMemShare = 1024;
m_hShareMem = CreateFileMappingW(INVALID_HANDLE_VALUE, &attributes, PAGE_READWRITE|SEC_COMMIT, 0, cbMemShare, L"MyMemShare");

客户端(作为交互式用户):

// succeeds if SD has (A;;GRGW;;;IU), fails on (A;;GR;;;IU)
HANDLE hShareMem = OpenFileMappingW(PAGE_READONLY, 0, L"MyMemShare");
if (hShareMem == NULL)
{
    DWORD err = GetLastError();
}

最重要的是,我想不出一种方法可以让这个内存在没有写访问权限的情况下可以读访问。服务器应该有 read/write,客户端应该已经读取。我已经对此进行了研究,但还没有找到任何确定的东西。

感谢任何见解。

CreateFileMappingW()OpenFileMappingW() 使用不同的保护标志定义集。

CreateFileMappingW() 支持的标志在 CreateFileMappingW function 文档中列出:

flProtect

Specifies the page protection of the file mapping object. All mapped views of the object must be compatible with this protection.

This parameter can be one of the following values.

PAGE_EXECUTE_READ
PAGE_EXECUTE_READWRITE
PAGE_EXECUTE_WRITECOPY
PAGE_READONLY
PAGE_READWRITE
PAGE_WRITECOPY

An application can specify one or more of the following attributes for the file mapping object by combining them with one of the preceding page protection values.

SEC_COMMIT
SEC_IMAGE
SEC_IMAGE_NO_EXECUTE
SEC_LARGE_PAGES
SEC_NOCACHE
SEC_RESERVE
SEC_WRITECOMBINE

OpenFileMappingW() 支持的标志在 OpenFileMappingW function 文档中列出:

dwDesiredAccess

The access to the file mapping object. This access is checked against any security descriptor on the target file mapping object. For a list of values, see File Mapping Security and Access Rights.

File Mapping Security and Access Rights 文档说:

The following table lists the access rights that are specific to file-mapping objects.

FILE_MAP_ALL_ACCESS
FILE_MAP_EXECUTE
FILE_MAP_READ
FILE_MAP_WRITE

调用OpenFileMappingW()时,需要使用FILE_MAP_READ而不是PAGE_READONLY。如果您查看 FILE_MAP_READPAGE_READONLY 的数值:

winbase.h

#define FILE_MAP_READ   4
#define FILE_MAP_WRITE  2

winnt.h

#define PAGE_READONLY       0x02

如您所见,FILE_MAP_READ为4,而PAGE_READONLY为2,与FILE_MAP_WRITE的数值相同。因此,您的客户端实际上是在请求对映射的写访问权限,这就是安全描述符需要包含写访问权限的原因。