fix(mesh): plug pooled-object and driver leaks in core paths (#11450)
- MeshService::sendQueueStatusToPhone: release the pooled QueueStatus when the toPhone queue enqueue fails, matching what sendMqttMessageToClientProxy and sendClientNotification already do. The full-queue guard makes this failure rare, but the check/enqueue sequence is not atomic and this path is reachable concurrently from the main loop and the nRF52 BLE write callback; each failure permanently lost one of the four pool slots, and after four losses the phone never receives QueueStatus again until reboot. - MessageStore::storeTextInPool: bail out when the boot-time pool allocation failed instead of memcpy'ing through a null pointer. The read side (getTextFromPool) already guards and maps offset 0 to an empty string. - RF95Interface: hold the RadioLibRF95 driver in a unique_ptr. It is constructed in init(), and when init() subsequently fails (e.g. chip probe NOT_FOUND) initLoRa() destroys the interface, leaking the driver; every sibling interface holds its driver by value so nothing else needed a destructor here.
This commit is contained in:
4 files changed
+15
-2
No files matched your search
@@ -42,6 +42,10 @@ static inline void resetMessagePool()
|
||||
// If not enough space remains, wrap around (ring buffer style)
|
||||
static inline uint16_t storeTextInPool(const char *src, size_t len)
|
||||
{
|
||||
// Pool allocation can fail at boot; getTextFromPool() already maps offset 0 to "" in that case
|
||||
if (!g_messagePool)
|
||||
return 0;
|
||||
|
||||
if (len >= MAX_MESSAGE_SIZE)
|
||||
len = MAX_MESSAGE_SIZE - 1;
|
||||
|
||||
|
||||
@@ -353,6 +353,8 @@ ErrorCode MeshService::sendQueueStatusToPhone(const meshtastic_QueueStatus &qs,
|
||||
lastQueueStatus = *copied;
|
||||
|
||||
res = toPhoneQueueStatusQueue.enqueue(copied, 0);
|
||||
if (!res)
|
||||
releaseQueueStatusToPool(copied);
|
||||
fromNum++;
|
||||
|
||||
return res ? ERRNO_OK : ERRNO_UNKNOWN;
|
||||
|
||||
@@ -129,7 +129,8 @@ bool RF95Interface::init()
|
||||
|
||||
limitPower(RF95_MAX_POWER);
|
||||
|
||||
iface = lora = new RadioLibRF95(&module);
|
||||
lora.reset(new RadioLibRF95(&module));
|
||||
iface = lora.get();
|
||||
|
||||
#ifdef RF95_TCXO
|
||||
pinMode(RF95_TCXO, OUTPUT);
|
||||
|
||||
@@ -4,12 +4,18 @@
|
||||
#include "RadioLibInterface.h"
|
||||
#include "RadioLibRF95.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* Our new not radiohead adapter for RF95 style radios
|
||||
*/
|
||||
class RF95Interface : public RadioLibInterface
|
||||
{
|
||||
RadioLibRF95 *lora = NULL; // Either a RFM95 or RFM96 depending on what was stuffed on this board
|
||||
// Either a RFM95 or RFM96 depending on what was stuffed on this board.
|
||||
// Owned here; every other radio interface holds its driver by value, but this one is
|
||||
// constructed in init(), so unique_ptr keeps it from leaking when init() fails and the
|
||||
// interface is destroyed.
|
||||
std::unique_ptr<RadioLibRF95> lora;
|
||||
|
||||
public:
|
||||
RF95Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
|
||||
|
||||
Reference in New Issue
Block a user