fix: add input validation for protocol decoding and fragment reassembly (#666)

* fix: add input validation for protocol decoding and fragment reassembly

* fix:subtract the old entry's size before adding the new one, so duplicate/retransmitted fragments don't inflate the counter

* fix: FragmentManager.handleFragment() can be entered concurrently (e.g., fragments for the same fragmentID arriving from multiple peers/relays). In order for this to happen multiple devices would be needed to connect to the mesh. even with a per-fragmentID byte cap, an attacker could open many fragment IDs at once and force the device to buffer lots of fragment data overall (risking memory pressure/OOM). In this fix we made fragments atomic and thread safe. When a fragment index is retransmitted, we compute the size delta (new - old) so duplicates don’t inflate counters and can’t be used to bypass limits. Under heavy load/attack the app will drop/reject fragment sets earlier instead of growing memory usage without bound to reduce risk of oom. tested on pixel 6 and pixel 8.

* fix: add fragmenttest
This commit is contained in:
Ovi
2026-03-26 16:24:29 +01:00
committed by GitHub
parent 96b35e957c
commit 5b0a7d0ce9
3 changed files with 159 additions and 72 deletions
@@ -41,6 +41,10 @@ object AppConstants {
const val MAX_FRAGMENT_SIZE: Int = 469
const val FRAGMENT_TIMEOUT_MS: Long = 30_000L
const val CLEANUP_INTERVAL_MS: Long = 10_000L
const val MAX_FRAGMENTS_PER_ID: Int = 256
const val MAX_FRAGMENT_TOTAL_BYTES: Int = 1_048_576
const val MAX_ACTIVE_FRAGMENT_SETS: Int = 64
const val MAX_GLOBAL_FRAGMENT_TOTAL_BYTES: Long = 4L * 1_048_576L
}
object Security {
@@ -64,6 +68,7 @@ object AppConstants {
object Protocol {
const val COMPRESSION_THRESHOLD_BYTES: Int = 100
const val MAX_PAYLOAD_LENGTH: Int = 10_485_760
}
object StoreForward {