Не могу открыть семафор из другого процесса - PullRequest
3 голосов
/ 09 февраля 2012

Я создаю объект глобального семафора в процессе, подобном этому:

CreateSemaphore(NULL, 1, 1, "Global\\bitmap");

сейчас, когда я пытаюсь открыть его в дочернем процессе (это специальныйв случае «другого процесса» это не будет дочерний элемент, который открывает созданный семафор), например:

bitmapSem = OpenSemaphore(NULL, TRUE, "Global\\bitmap");

переменная bitmapSem равна NULL и I 'получаю ошибку 5 (ERROR_ACCESS_DENIED) от GetLastError().

Есть идеи?

Ответы [ 3 ]

7 голосов
/ 09 февраля 2012

Первый аргумент OpenSemaphore() задокументирован как:

dwDesiredAccess [in]

Доступ к объекту семафора. Функция завершается ошибкой, если дескриптор безопасности указанного объекта не разрешает запрашиваемый доступ для вызывающего процесса. Список прав доступа см. В разделе Безопасность объекта синхронизации и права доступа.

В размещенном коде указан NULL, который не задокументирован как имеющий особое значение. Измените одно из прав доступа, указанных в Безопасность объекта синхронизации и Права доступа :

bitmapSem = OpenSemaphore(SYNCHRONIZE, TRUE, "Global\\bitmap");

EDIT:

Чтобы создать дескриптор безопасности, который предоставил бы доступ к Everyone, попробуйте следующий (непроверенный) код:

/* Create a security descriptor that has an an empty DACL, to
   grant access to 'Everyone'. */
SECURITY_DESCRIPTOR sd;
if (0 == InitializeSecurityDescriptor(&sd,
                                      SECURITY_DESCRIPTOR_REVISION) ||
    0 == SetSecurityDescriptorDacl(&sd,
                                   TRUE,
                                   (PACL)0,
                                   FALSE))
{
    /* Failed to create security descriptor. */
}
else
{
    SECURITY_ATTRIBUTES sa;
    sa.nLength              = sizeof(sa);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle       = FALSE;

    HANDLE sh = CreateSemaphore(&sa, 1, 1, "Global\\bitmap");
}
7 голосов
/ 10 февраля 2012

Я должен добавить пояснение к другим ответам и предупреждение безопасности.

Во-первых, передача значения NULL в качестве аргумента lpSemaphoreAttributes для ::CreateSemaphore() означает , а не означает отсутствие доступа ни к кому;скорее это означает, что будет назначено управление доступом по умолчанию. MSDN кристально чист на этом : Если этот параметр имеет значение NULL, семафор получает дескриптор безопасности по умолчанию.ACL-списки в дескрипторе безопасности по умолчанию для семафора происходят из основного маркера или маркера олицетворения создателя.

Обычно семафор может открываться и использоваться одним и тем же идентификатором пользователя.Таким образом, если семафор используется совместно процессами, выполняющимися в одном и том же интерактивном сеансе или под одним и тем же идентификатором службы, он может быть открыт другим процессом, даже если он создан с дескриптором безопасности по умолчанию.Как уже отмечалось @hmjd, вы всегда должны явно вызывать право, которое вы хотите отстаивать на семафоре: SYNCHRONIZE|SEMAPHORE_MODIFY_STATE позволяет как ждать, так и освободить его.

Во-вторых, слово предостережения.Предоставляя всем полный доступ к семафору, как это было предложено выше, потенциально создается дыра в безопасности для DoS-атаки.Вы должны подумать, хотите ли вы, чтобы произвольные процессы могли захватывать и освобождать семафор.Предназначено ли оно для неограниченного публичного использования?Хорошей практикой всегда является назначение минимальных, узко разрешенных списков ACL для объектов.Использование SDDL , вероятно, является самым простым способом кодирования дескриптора безопасности, хотя сам скрипт не очень удобочитаем.

0 голосов
/ 09 февраля 2012

lpSemaphoreAttributes [in, необязательно]
Указатель на Структура SECURITY_ATTRIBUTES. Если этот параметр равен NULL, дескриптор не может наследоваться дочерними процессами.

Передайте LPSECURITY_ATTRIBUTES с пустым DACL и членом bInheritHandle, соответствующим образом установленным в качестве 1-го аргумента.

Примером на VB будет:

'Setup the security descriptor
InitializeSecurityDescriptor SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION
SetSecurityDescriptorDacl SecurityDescriptor, 1, ByVal 0, 0 'Dacl is present and empty

'Setup the security attributes
SecurityAttributes.nLength = Len(SecurityAttributes)
SecurityAttributes.lpSecurityDescriptor = VarPtr(SecurityDescriptor)
SecurityAttributes.bInheritHandle = False
...