Destroy promise/future callback functions before waking waiters
authorYedidya Feldblum <yfeldblum@fb.com>
Tue, 9 May 2017 01:50:51 +0000 (18:50 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Tue, 9 May 2017 01:51:37 +0000 (18:51 -0700)
commit0be5c0a490a250b05590c62a9c70b6f654bfb546
tree033fd74b31d99a4b6f02dd3a6cc1a9076e1ce281
parentd5986bf055513d4ca02b27234afff6a841f9ba00
Destroy promise/future callback functions before waking waiters

Summary:
Code may pass a callback which captures an object with a destructor which mutates through a stored reference, triggering heap-use-after-free or stack-use-after-scope.

```lang=c++
void performDataRace() {
  auto number = std::make_unique<int>(0);
  auto guard = folly::makeGuard([&number] { *number = 1; });
  folly::via(getSomeExecutor(), [guard = std::move(guard)]() mutable {}).wait();
  // data race - we may wake and destruct number before guard is destructed on the
  // executor thread, which is both stack-use-after-scope and heap-use-after-free!
}
```

We can avoid this condition by always destructing the provided functor before setting any result on the promise.

Reviewed By: spacedentist

Differential Revision: D4982969

fbshipit-source-id: 71134c1657bdd4c38c12d8ca17f8335ef4c27352
folly/futures/Future-inl.h
folly/futures/Promise-inl.h
folly/futures/Promise.h
folly/futures/test/CallbackLifetimeTest.cpp [new file with mode: 0644]
folly/test/Makefile.am