Fix onWritable calling markDone resulting in potential heap-use-after-free

This commit is contained in:
Alex Hultman
2022-05-02 01:38:11 +02:00
parent 44af0e5710
commit e4c6fbf8de
3 changed files with 33 additions and 13 deletions
+30
View File
@@ -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 {