Skip to content

Commit d320c97

Browse files
authored
Fix possible crash in UdpContext host mocking.
I saw this crash in UdpContext.h happen after some hours of regular NTP requests.... ``` [17:38:51] ADE: voltage spike: phase A, factor=0.81, cycles=1 (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused [17:41:14] ADE: voltage spike: phase A, factor=0.86, cycles=2 (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused (mock) ClientContext::connect: ::connect(): Connection refused [17:43:49] ADE: voltage spike: phase B, factor=1.12, cycles=3 (mock) ClientContext::connect: ::connect(): Connection refused (mock) =====> UdpServer port: 2390 <===== [17:44:31] NTP: waiting for response from '81.169.233.252' timed out Program received signal SIGSEGV, Segmentation fault. 0x000055555556848c in std::_Function_base::_M_empty() const () (gdb) where #0 0x000055555556848c in std::_Function_base::_M_empty() const () #1 0x00005555555685be in std::function<void ()>::operator bool() const () #2 0x00005555555684b8 in UdpContext::mock_cb() () #3 0x00005555555683af in check_incoming_udp() () #4 0x0000555555567fa6 in main () ``` I tracked it down to UdpContext::mock_cb() which is calling a std::function callback that's been destroyed thus used-after-free. I believe what happens is: 1. UdpContext::unref() calls delete this when refcount hits 0 (line 56) 2. The destructor (~UdpContext(), line 47) is empty — it never calls register_udp(_sock, nullptr) to remove itself from the global udps map 3. check_incoming_udp() iterates udps, finds the dangling pointer, calls mock_cb() on freed memory 4. _on_rx (a destroyed std::function) → segfault in _M_empty() The disconnect() method already does the right thing (lines 78-84: closes socket + unregisters), but it's never called before the object is destroyed via unref(). The fix is to make the destructor clean up properly. I tested intensely, no crashes since.
1 parent 7b0ac41 commit d320c97

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

tests/host/common/include/UdpContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class UdpContext
4444
_sock = mockUDPSocket();
4545
}
4646

47-
~UdpContext() { }
47+
~UdpContext() { disconnect(); }
4848

4949
void ref()
5050
{

0 commit comments

Comments
 (0)