getByIndex allocates memory and returns dummy channel whenever
chIndex validation fails. Comment implies this may happen
when malformed packet is received. The fix changes implementation
so static dummyChannel is returned in such case.
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* enhance tx queue priority management
In busy environments, especially for ROUTER_LATE role, tx queue
fills very quickly. Delayed packets became late but new packets
to be retransmitted won't be put into the tx queue as old ones
stay there for a very long time (even a minute or more). This change
makes meshtastic prioritize new packets over late packets from tx queue
and allows to remove late packet from back of tx queue when there
is no space for a new one.
* apply copilot recommendation for cast
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Three-agent security audit of the LOCKDOWN build identified race conditions,
incomplete key zeroing, and missing memory hygiene. All findings except HIGH-1
are addressed here. HIGH-1 (revokeAllAuth not resetting per-instance
isAdminAuthorized) was reviewed and closed as wontfix: PKC admin key holders
have persistent access regardless, so the 7-second pre-reboot window changes
nothing about the threat model.
HIGH-2: lockNow() previously only zeroed dek[]. Now also zeroes kek[],
ephemeralKek[], and their derived flags so no key material survives a lock
event in a RAM dump.
HIGH-3: isAdminAuthorized (per-instance) and s_localAdminAuthorized (static)
changed from plain bool to std::atomic<bool>. Both flags are written from the
NimBLE FreeRTOS task and read from the main loop — non-atomic reads were a
data race.
MED-1: readAndDecrypt() and encryptAndWrite() now snapshot dek[] into a stack-
local dekSnapshot[] on entry before acquiring any lock. A concurrent lockNow()
that zeros dek[] mid-operation either zeroes the snapshot (HMAC fails securely)
or has no effect on an already-captured copy. dekSnapshot is zeroed on all exit
paths.
MED-2: close() and handleStartConfig() no longer clear s_localAdminAuthorized.
Resetting it on every disconnect was an auth DoS — any new client connection
would silently revoke the passphrase-authenticated state, forcing the operator
to re-enter the passphrase on every reconnect. Device-level auth now persists
until explicit Lock Now (revokeAllAuth()).
MED-3: readAndDecrypt() scoped the spiLock LockGuard to a nested block
covering only the FSCom.open/read/close sequence. The lock is released before
any HMAC or AES-CTR work. spiLock is a non-recursive binary semaphore;
holding it across CC310 calls created a re-entry deadlock risk.
MED-4: AdminModule zeros the passphrase bytes in toRadioScratch via a volatile
pointer cast before returning from both the Lock Now and provision/unlock
paths. Prevents the passphrase lingering in the scratch buffer until the next
ToRadio message overwrites it.
MED-5: readAndDecrypt() was missing memset(fileBuf) on the hmacData OOM early-
exit path, leaving ciphertext in the heap until the allocator reuses it.
MED-6: readAndDecrypt() now sets outLen=0 on entry so callers never observe a
stale length value on any early failure return.
MED-7: readAndDecrypt() calls memset(outBuf, 0, ciphertextLen) on AES-CTR
failure to clear partial plaintext that may have been written to the caller's
buffer before the error was detected.
MED-8: Passphrase length limit corrected from 64 to 32 bytes throughout
(EncryptedStorage.cpp provisionPassphrase/unlockWithPassphrase, AdminModule.cpp
ppLen range check, EncryptedStorage.h doc comments). The proto private_key field
is 32 bytes; accepting 33-64 silently failed inside EncryptedStorage while
appearing to succeed at the AdminModule gate.
L-1: readAndDecrypt() now rejects files larger than 65536+54 bytes before
allocating the heap buffer, preventing OOM or integer overflow on corrupt or
attacker-supplied oversized files.
L-2: migrateFile() has a precondition comment that spiLock must not be held
by the caller; both isEncrypted() and encryptAndWrite() acquire it internally.
* Don't launch canned message when waking screen or silencing notification
* Add screen ifdefs
* Get the #if right
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* fix(MQTT): First MapReport does not get sent
Throttle::isWithinTimespanMs(last_report_to_map, map_publish_interval_msecs) is
used to maintain the map reporting interval, but because last_report_to_map has
an initial value of 0, the map report routine does not start until the system
millis() time has passed map_publish_interval_msecs.
Fix this by adding a check that last_report_to_map is not 0.
Signed-off-by: Andrew Yong <me@ndoo.sg>
* feat(MQTT): Send MapReporting immediately upon location fix
Do not update last_report_to_map when Map Report is attempted without a valid
location, as this results in waiting up to an hour (or configured Map Report
interval).
That usually happens because most nodes do not keep GPS warm, so GPS usually
locks after the first attempt at Map Report.
This change also results in the log WARNing message getting spammed until a
location is obtained, so remove the message for now.
Signed-off-by: Andrew Yong <me@ndoo.sg>
* feat(MQTT): Throttled warning when position is not available for MapReport
Signed-off-by: Andrew Yong <me@ndoo.sg>
---------
Signed-off-by: Andrew Yong <me@ndoo.sg>
* Add transmit history for throttling that persists between reboots
* Fix RAK long press detection to prevent phantom shutdowns from floating pins
* Update test/test_transmit_history/test_main.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Test fixes and placeholder for content handler tests
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Change file name from BLEDfuScure.cpp to BLEDfuSecure.cpp. Fix filenames
in documentation.
Signed-off-by: Koko <github@kokosoftware.pl>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* Add GPIO_DETECT_PA portduino config, and support 13302 detection with it.
* Tweak PA detect gpio to use pinMapping
* minor yaml output fixes
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
* Align telemetry broadcast want_response behavior with traceroute
* Fixes
* Reduce side-effects by making the telemetry modules handle the ignorerequest
* Remove unnecessary ignoreRequest flag
* Try inheriting from MeshModule
* Add exclusion for sensor/router roles and add base telem module
* Implement 'agc' reset for SX126x chip family
There's no actual agc on SX126x chips but you can reset the analog
registers by doing a warm sleep & running calibration.
* Address PR comments & implement for LR11x0 too
* calibrate for configured frequency band
* Gate LR11X0_AGC_RESET
* Apply SX1262 register 0x8B5 patch for improved GC1109 RX sensitivity
Sets the LSB of undocumented SX1262 register 0x8B5 on Heltec V4 and
Wireless Tracker V2 boards with the GC1109 FEM. This patch was
recommended by Heltec/Semtech and tested in MeshCore PR #1398, where
it significantly reduced packet loss on the Heltec V4.
* Use higher level function
* Add .venv/ to .gitignore
* Reduce maximum concurrent HTTPS connections to save memory
* Add heap check and limit connections to prevent HTTPS connection related crashes
* Use Throttle::isWithinTimespanMs for overflow-safe heap warning throttle
* Update src/mesh/http/WebServer.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix double-free heap corruption and parser leak in web server handlers
- Remove double-free in handleFsBrowseStatic, handleNodes, handleScanNetworks:
JSONValue(const JSONArray&) shallow-copies pointers, so delete value already
recursively frees all elements. The explicit cleanup loops were deleting the
same pointers a second time, corrupting the ESP32 heap allocator metadata.
This is the likely root cause of #8827 (SSL setup failures after uptime).
- Fix memory leak in handleFormUpload: two early-return paths were missing
delete parser.
- Remove unused global HTTPClient httpClient and its includes.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>