Commit b756d166 authored by Robin Cheng's avatar Robin Cheng Committed by Facebook GitHub Bot

Unregister event handler fd before closing the fd in EventBaseAtomicNotificationQueue.

Summary:
Thread 1:
  - Creates an eventfd X
  - Registers X with an event base
  - Closes X
  - Unregisters X from the event base

Thread 2:
  - Creates some other file descriptor (eventfd or socket or whatever); the operating system reuses file descriptor #X.

The unregistering of X from the event base in thread 1 races with the opening of reused X in thread 2.

The fix is to unregister X before closing X.

Reviewed By: yfeldblum

Differential Revision: D27962155

fbshipit-source-id: 1bcb62c7ebe0297ab9687e1a0edf37d319637fda
parent 0297c176
...@@ -78,6 +78,11 @@ EventBaseAtomicNotificationQueue<Task, Consumer>:: ...@@ -78,6 +78,11 @@ EventBaseAtomicNotificationQueue<Task, Consumer>::
[](Task&&) { return AtomicNotificationQueueTaskStatus::DISCARD; })) { [](Task&&) { return AtomicNotificationQueueTaskStatus::DISCARD; })) {
} }
// We must unregister before closing the fd. Otherwise the base class
// would unregister the fd after it's already closed, which is invalid
// (some other thread could've opened something that reused the fd).
unregisterHandler();
// Don't drain fd in the child process. // Don't drain fd in the child process.
if (pid_ == get_cached_pid()) { if (pid_ == get_cached_pid()) {
// Wait till we observe all the writes before closing fds // Wait till we observe all the writes before closing fds
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment