Destroy promise/future callback functions before waking waiters
authorYedidya Feldblum <yfeldblum@fb.com>
Thu, 1 Jun 2017 05:41:16 +0000 (22:41 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Thu, 1 Jun 2017 05:51:28 +0000 (22:51 -0700)
commit8e110a76171f5204d63ce3dbd283589f8914fe44
tree2a95d049e25cb1df9380c82c694525f3ce54296c
parent3a4a9694164306e5279fd1df1689af1bcdeb4a89
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.

Retry at {D4982969}.

Reviewed By: andriigrynenko

Differential Revision: D5058750

fbshipit-source-id: 4d1d878b4889e5e6474941187f03de5fa84d3061
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