summaryrefslogtreecommitdiff
path: root/src/event
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2019-04-03 23:23:56 +0200
committerMax Kellermann <max@musicpd.org>2019-04-04 10:24:58 +0200
commitf6941f9a44037da0b7a1407052bd207d988273d7 (patch)
tree6feed0c7033d0282c367ecfbc32171b603850f50 /src/event
parentd2eb4df8fc61c4c66e29804f334e2d0e935c7ba9 (diff)
event/SocketMonitor: don't cancel if OnSocketReady() returns false
Expect OnSocketReady() to cancel events. If it returns false, the SocketMonitor may be destructed already. This fixes a use-after-free bug in the "httpd" output plugin.
Diffstat (limited to 'src/event')
-rw-r--r--src/event/BufferedSocket.cxx8
-rw-r--r--src/event/SocketMonitor.cxx4
2 files changed, 3 insertions, 9 deletions
diff --git a/src/event/BufferedSocket.cxx b/src/event/BufferedSocket.cxx
index c66eb9f42..ace399893 100644
--- a/src/event/BufferedSocket.cxx
+++ b/src/event/BufferedSocket.cxx
@@ -110,15 +110,9 @@ BufferedSocket::OnSocketReady(unsigned flags) noexcept
if (flags & READ) {
assert(!input.IsFull());
- if (!ReadToBuffer())
+ if (!ReadToBuffer() || !ResumeInput())
return false;
- if (!ResumeInput())
- /* we must return "true" here or
- SocketMonitor::Dispatch() will call
- Cancel() on a freed object */
- return true;
-
if (!input.IsFull())
ScheduleRead();
}
diff --git a/src/event/SocketMonitor.cxx b/src/event/SocketMonitor.cxx
index 0b2a36088..64cc42820 100644
--- a/src/event/SocketMonitor.cxx
+++ b/src/event/SocketMonitor.cxx
@@ -33,8 +33,8 @@ SocketMonitor::Dispatch(unsigned flags) noexcept
{
flags &= GetScheduledFlags();
- if (flags != 0 && !OnSocketReady(flags) && IsDefined())
- Cancel();
+ if (flags != 0)
+ OnSocketReady(flags);
}
SocketMonitor::~SocketMonitor() noexcept