Fix onWritable calling markDone resulting in potential heap-use-after-free
This commit is contained in:
@@ -32,6 +32,36 @@ template <bool SSL>
|
||||
struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
|
||||
template <bool> friend struct HttpResponse;
|
||||
template <bool> friend struct HttpContext;
|
||||
|
||||
/* When we are done with a response we mark it like so */
|
||||
void markDone() {
|
||||
onAborted = nullptr;
|
||||
/* Also remove onWritable so that we do not emit when draining behind the scenes. */
|
||||
onWritable = nullptr;
|
||||
|
||||
/* We are done with this request */
|
||||
state &= ~HttpResponseData<SSL>::HTTP_RESPONSE_PENDING;
|
||||
}
|
||||
|
||||
/* Caller of onWritable. It is possible onWritable calls markDone so we need to borrow it. */
|
||||
bool callOnWritable(uintmax_t offset) {
|
||||
/* Borrow real onWritable */
|
||||
MoveOnlyFunction<bool(uintmax_t)> borrowedOnWritable = std::move(onWritable);
|
||||
|
||||
/* Set onWritable to placeholder */
|
||||
onWritable = [](uintmax_t) {return true;};
|
||||
|
||||
/* Run borrowed onWritable */
|
||||
bool ret = borrowedOnWritable(offset);
|
||||
|
||||
/* If we still have onWritable (the placeholder) then move back the real one */
|
||||
if (onWritable) {
|
||||
/* We haven't reset onWritable, so give it back */
|
||||
onWritable = std::move(borrowedOnWritable);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
/* Bits of status */
|
||||
enum {
|
||||
|
||||
Reference in New Issue
Block a user