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.
This commit is contained in:
parent
d2eb4df8fc
commit
f6941f9a44
1
NEWS
1
NEWS
|
@ -1,6 +1,7 @@
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
{
|
{
|
||||||
flags &= GetScheduledFlags();
|
flags &= GetScheduledFlags();
|
||||||
|
|
||||||
if (flags != 0 && !OnSocketReady(flags) && IsDefined())
|
if (flags != 0)
|
||||||
Cancel();
|
OnSocketReady(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketMonitor::~SocketMonitor() noexcept
|
SocketMonitor::~SocketMonitor() noexcept
|
||||||
|
|
Loading…
Reference in New Issue