Commit f6941f9a authored by Max Kellermann's avatar Max Kellermann

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.
parent d2eb4df8
ver 0.21.8 (not yet released) ver 0.21.8 (not yet released)
* output * output
- httpd: add missing mutex lock - httpd: add missing mutex lock
- httpd: fix use-after-free bug
* fix Bonjour bug * fix Bonjour bug
* fix build failure with GCC 9 * fix build failure with GCC 9
......
...@@ -568,7 +568,8 @@ ProxyDatabase::OnSocketReady(gcc_unused unsigned flags) noexcept ...@@ -568,7 +568,8 @@ ProxyDatabase::OnSocketReady(gcc_unused unsigned flags) noexcept
if (!is_idle) { if (!is_idle) {
// TODO: can this happen? // TODO: can this happen?
IdleMonitor::Schedule(); IdleMonitor::Schedule();
return false; SocketMonitor::Cancel();
return true;
} }
unsigned idle = (unsigned)mpd_recv_idle(connection, false); unsigned idle = (unsigned)mpd_recv_idle(connection, false);
...@@ -586,7 +587,8 @@ ProxyDatabase::OnSocketReady(gcc_unused unsigned flags) noexcept ...@@ -586,7 +587,8 @@ ProxyDatabase::OnSocketReady(gcc_unused unsigned flags) noexcept
idle_received |= idle; idle_received |= idle;
is_idle = false; is_idle = false;
IdleMonitor::Schedule(); IdleMonitor::Schedule();
return false; SocketMonitor::Cancel();
return true;
} }
void void
......
...@@ -110,15 +110,9 @@ BufferedSocket::OnSocketReady(unsigned flags) noexcept ...@@ -110,15 +110,9 @@ BufferedSocket::OnSocketReady(unsigned flags) noexcept
if (flags & READ) { if (flags & READ) {
assert(!input.IsFull()); assert(!input.IsFull());
if (!ReadToBuffer()) if (!ReadToBuffer() || !ResumeInput())
return false; return false;
if (!ResumeInput())
/* we must return "true" here or
SocketMonitor::Dispatch() will call
Cancel() on a freed object */
return true;
if (!input.IsFull()) if (!input.IsFull())
ScheduleRead(); ScheduleRead();
} }
......
...@@ -33,8 +33,8 @@ SocketMonitor::Dispatch(unsigned flags) noexcept ...@@ -33,8 +33,8 @@ SocketMonitor::Dispatch(unsigned flags) noexcept
{ {
flags &= GetScheduledFlags(); flags &= GetScheduledFlags();
if (flags != 0 && !OnSocketReady(flags) && IsDefined()) if (flags != 0)
Cancel(); OnSocketReady(flags);
} }
SocketMonitor::~SocketMonitor() noexcept SocketMonitor::~SocketMonitor() noexcept
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment