Commit d320c97
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
1 file changed
+1
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
47 | | - | |
| 47 | + | |
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| |||
0 commit comments