fix(radio): MeshBeacon heap leak and runtime packet payload size check (#11573)

* Fix for MeshBeacon packet leakage

* fix: add runtime payload size check against radiobuffer

* review fix for PR#11573: clear target radio settings before MeshBeacon packet release

* add unit test for radio buffer capacity check, removing related assert for the test

* review fix for PR#11573: add explicit verifaction against rejected packets
This commit is contained in:
Tadayoshi MIURA
2026-08-23 11:00:30 +00:00
committed by GitHub
parent 05f6474108
commit ac330e6a6b
4 files changed
+58 -5

No files matched your search

+29
View File
@@ -60,6 +60,10 @@ class TestableRadioInterface : public RadioInterface
uint8_t getSf() const { return sf; }
float getBw() const { return bw; }
size_t beginSendingPublic(meshtastic_MeshPacket *p) { return beginSending(p); }
meshtastic_MeshPacket *getSendingPacket() const { return sendingPacket; }
size_t getRadioBufferPayloadCapacity() const { return sizeof(radioBuffer.payload); }
// Override reconfigure to call the base which invokes applyModemConfig()
bool reconfigure() override { return RadioInterface::reconfigure(); }
@@ -413,6 +417,30 @@ static void test_regionPresetMap_unsetCarriesUserprefsIntent()
#endif
}
static void test_beginSending_oversizedPayloadAbortsSafely()
{
meshtastic_MeshPacket *p = packetPool.allocZeroed();
TEST_ASSERT_NOT_NULL(p);
p->from = 0x12345678;
p->to = 0x87654321;
p->id = 0x10203040;
p->which_payload_variant = meshtastic_MeshPacket_encrypted_tag;
// Set encrypted size larger than sizeof(radioBuffer.payload) (which is 256 - sizeof(PacketHeader))
p->encrypted.size = testRadio->getRadioBufferPayloadCapacity() + 10;
size_t result = testRadio->beginSendingPublic(p);
TEST_ASSERT_EQUAL_UINT(0, result);
TEST_ASSERT_NULL(testRadio->getSendingPacket());
// Verify rejected packet was released to packetPool and its slot is reusable
meshtastic_MeshPacket *reallocated = packetPool.allocZeroed();
TEST_ASSERT_NOT_NULL(reallocated);
TEST_ASSERT_EQUAL_PTR(p, reallocated);
packetPool.release(reallocated);
}
void setUp(void)
{
mockMeshService = new MockMeshService();
@@ -463,6 +491,7 @@ void setup()
RUN_TEST(test_regionPresetMap_coversAllRegionsWithinBounds);
RUN_TEST(test_regionPresetMap_matchesRegionTable);
RUN_TEST(test_regionPresetMap_unsetCarriesUserprefsIntent);
RUN_TEST(test_beginSending_oversizedPayloadAbortsSafely);
exit(UNITY_END());
}