Answer to quick puzzle about security and synchronization

Date:June 7, 2005 / year-entry #143
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20050607-34/?p=35403
Comments:    5
Summary:As many people quickly figured out, the reason why the the WaitForSingleObject returns immediately is that the call is failing. The reason is that the second process opened the handle with EVENT_MODIFY_STATE access, which grants permission to call the SetEvent function, the ResetEvent function, and the fatally flawed PulseEvent function, but it doesn't include SYNCHRONIZE...

As many people quickly figured out, the reason why the the WaitForSingleObject returns immediately is that the call is failing. The reason is that the second process opened the handle with EVENT_MODIFY_STATE access, which grants permission to call the SetEvent function, the ResetEvent function, and the fatally flawed PulseEvent function, but it doesn't include SYNCHRONIZE access, which is necessary if you intend to synchronize on the object (i.e., wait on it).

The fix is for Process B to ask for SYNCHRONIZE access instead of EVENT_MODIFY_STATE.

The fact that it's happening in a second process is a red herring. You can put this code in the same process and it will fail/succeed in the same way:

HANDLE hEventA = CreateEvent(NULL, FALSE, TRUE, TEXT("MyNamedEvent"));
HANDLE hEventB = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("MyNamedEvent"));
WaitForSingleObject(hEventB, INFINITE); // fails

Indeed, the fact that the object is named is a red herring. It has nothing to do with named/unnamed objects.

HANDLE hEventA = CreateEvent(NULL, FALSE, TRUE, NULL);
HANDLE hEventB;
DuplicateHandle(GetCurrentProcess(), hEventA,
                GetCurrentProcess(), &hEventB,
                EVENT_MODIFY_STATE, FALSE, 0);
WaitForSingleObject(hEventB, INFINITE); // fails

In all three cases, the fix is to change EVENT_MODIFY_STATE to SYNCHRONIZE.


Comments (5)
  1. Jonathan says:

    And of course, a named handle with a hardcoded name is very easy to squat. Any app can register/signal that event, thus affecting your prog into unfavorable situation (denial of service, maybe worse things)

  2. denis bider says:

    Since it doesn’t seem to be possible to post under the PulseEvent blog entry any more, I’ll post it here: PulseEvent is not flawed. Rather, what is flawed is a programmer trying to use it as means to signal a specific thread.

    The contract of PulseEvent is that it will wake up 0 or 1 thread, depending on circumstances. If you’re not content with the 0 outcome, don’t use PulseEvent.

  3. Dave says:

    This is sorta off topic but I am just curious. What is your job at Microsoft? It sounds like you did some core work back in the day (because you did some power toys) but moved into App Compat (apparently). Your posts are very intuitive and interesting, you have posted very.. enlightening scenarios. Somewhat related but not totally, at the Microsoft Community Blogs page, I looked for your blog under App Compate and found nothing, what category are you under?

  4. Foolhardy says:

    Jonathan: If you call CreateEvent, and an event with that name already exists, it will give you a new handle to that event and GetLastError() will return ERROR_ALREADY_EXISTS (183). This way, you can at least tell if the event existed already without causing a race condition.

  5. David,

    Raymond’s the wizard. That’s his job.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index