Fix for double-free (and possibly other memory-corruption related) crashes at logrotate time

this is a direct fix of the issue revealing the problem that leads to crash

verification done with a patched icinga2 where the execution-order of the code lines of counter-parts involved in re-incrementing/decrementing Timer:Ptr is forced to be the one that leads to the obeserverd segfaults

refs #6737

(cherry picked from commit 52e3db279ab9ff348456234b8a033e703c6f7580)
This commit is contained in:
Elias Ohm 2019-04-17 22:31:42 +02:00 committed by Michael Friedrich
parent 54538986b8
commit 304ba1fd6c
3 changed files with 4 additions and 6 deletions

View File

@ -127,7 +127,7 @@ void Timer::UninitializeThread()
void Timer::Call() void Timer::Call()
{ {
try { try {
OnTimerExpired(Timer::Ptr(this)); OnTimerExpired(this);
} catch (...) { } catch (...) {
InternalReschedule(true); InternalReschedule(true);
@ -318,8 +318,6 @@ void Timer::TimerThreadProc()
continue; continue;
} }
Timer::Ptr ptimer = timer;
/* Remove the timer from the list so it doesn't get called again /* Remove the timer from the list so it doesn't get called again
* until the current call is completed. */ * until the current call is completed. */
l_Timers.erase(timer); l_Timers.erase(timer);
@ -329,6 +327,6 @@ void Timer::TimerThreadProc()
lock.unlock(); lock.unlock();
/* Asynchronously call the timer. */ /* Asynchronously call the timer. */
Utility::QueueAsyncCallback(std::bind(&Timer::Call, ptimer)); Utility::QueueAsyncCallback(std::bind(&Timer::Call, timer));
} }
} }

View File

@ -56,7 +56,7 @@ public:
void Reschedule(double next = -1); void Reschedule(double next = -1);
double GetNext() const; double GetNext() const;
boost::signals2::signal<void(const Timer::Ptr&)> OnTimerExpired; boost::signals2::signal<void(const Timer * const&)> OnTimerExpired;
private: private:
double m_Interval{0}; /**< The interval of the timer. */ double m_Interval{0}; /**< The interval of the timer. */

View File

@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE(interval)
int counter = 0; int counter = 0;
static void Callback(const Timer::Ptr&) static void Callback(const Timer * const&)
{ {
counter++; counter++;
} }