mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-31 07:01:03 +00:00
Fix de/compression buffer overflows in TAK packets (#4317)
* Fix de/compression buffer overflows in TAK packets * Log message
This commit is contained in:
@@ -5,11 +5,8 @@
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "meshtastic/atak.pb.h"
|
||||
|
||||
extern "C" {
|
||||
#include "mesh/compression/unishox2.h"
|
||||
}
|
||||
#include "meshtastic/atak.pb.h"
|
||||
|
||||
AtakPluginModule *atakPluginModule;
|
||||
|
||||
@@ -69,30 +66,53 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast
|
||||
auto compressed = cloneTAKPacketData(t);
|
||||
compressed.is_compressed = true;
|
||||
if (t->has_contact) {
|
||||
auto length = unishox2_compress_simple(t->contact.callsign, strlen(t->contact.callsign), compressed.contact.callsign);
|
||||
auto length = unishox2_compress_lines(t->contact.callsign, strlen(t->contact.callsign), compressed.contact.callsign,
|
||||
sizeof(compressed.contact.callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compression overflowed contact.callsign. Reverting to uncompressed packet\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed callsign: %d bytes\n", length);
|
||||
|
||||
length = unishox2_compress_simple(t->contact.device_callsign, strlen(t->contact.device_callsign),
|
||||
compressed.contact.device_callsign);
|
||||
length = unishox2_compress_lines(t->contact.device_callsign, strlen(t->contact.device_callsign),
|
||||
compressed.contact.device_callsign, sizeof(compressed.contact.device_callsign) - 1,
|
||||
USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compression overflowed contact.device_callsign. Reverting to uncompressed packet\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed device_callsign: %d bytes\n", length);
|
||||
}
|
||||
if (t->which_payload_variant == meshtastic_TAKPacket_chat_tag) {
|
||||
auto length = unishox2_compress_simple(t->payload_variant.chat.message, strlen(t->payload_variant.chat.message),
|
||||
compressed.payload_variant.chat.message);
|
||||
auto length = unishox2_compress_lines(t->payload_variant.chat.message, strlen(t->payload_variant.chat.message),
|
||||
compressed.payload_variant.chat.message,
|
||||
sizeof(compressed.payload_variant.chat.message) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compression overflowed chat.message. Reverting to uncompressed packet\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed chat message: %d bytes\n", length);
|
||||
|
||||
if (t->payload_variant.chat.has_to) {
|
||||
compressed.payload_variant.chat.has_to = true;
|
||||
length = unishox2_compress_simple(t->payload_variant.chat.to, strlen(t->payload_variant.chat.to),
|
||||
compressed.payload_variant.chat.to);
|
||||
length = unishox2_compress_lines(t->payload_variant.chat.to, strlen(t->payload_variant.chat.to),
|
||||
compressed.payload_variant.chat.to,
|
||||
sizeof(compressed.payload_variant.chat.to) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compression overflowed chat.to. Reverting to uncompressed packet\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed chat to: %d bytes\n", length);
|
||||
}
|
||||
|
||||
if (t->payload_variant.chat.has_to_callsign) {
|
||||
compressed.payload_variant.chat.has_to_callsign = true;
|
||||
length =
|
||||
unishox2_compress_simple(t->payload_variant.chat.to_callsign, strlen(t->payload_variant.chat.to_callsign),
|
||||
compressed.payload_variant.chat.to_callsign);
|
||||
length = unishox2_compress_lines(t->payload_variant.chat.to_callsign, strlen(t->payload_variant.chat.to_callsign),
|
||||
compressed.payload_variant.chat.to_callsign,
|
||||
sizeof(compressed.payload_variant.chat.to_callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compression overflowed chat.to_callsign. Reverting to uncompressed packet\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed chat to_callsign: %d bytes\n", length);
|
||||
}
|
||||
}
|
||||
@@ -102,7 +122,7 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast
|
||||
} else {
|
||||
if (!t->is_compressed) {
|
||||
// Not compressed. Something is wrong
|
||||
LOG_ERROR("Received uncompressed TAKPacket over radio!\n");
|
||||
LOG_WARN("Received uncompressed TAKPacket over radio! Skipping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -112,32 +132,55 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast
|
||||
uncompressed.is_compressed = false;
|
||||
if (t->has_contact) {
|
||||
auto length =
|
||||
unishox2_decompress_simple(t->contact.callsign, strlen(t->contact.callsign), uncompressed.contact.callsign);
|
||||
|
||||
unishox2_decompress_lines(t->contact.callsign, strlen(t->contact.callsign), uncompressed.contact.callsign,
|
||||
sizeof(uncompressed.contact.callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompression overflowed contact.callsign. Bailing out\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed callsign: %d bytes\n", length);
|
||||
|
||||
length = unishox2_decompress_simple(t->contact.device_callsign, strlen(t->contact.device_callsign),
|
||||
uncompressed.contact.device_callsign);
|
||||
|
||||
length = unishox2_decompress_lines(t->contact.device_callsign, strlen(t->contact.device_callsign),
|
||||
uncompressed.contact.device_callsign,
|
||||
sizeof(uncompressed.contact.device_callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompression overflowed contact.device_callsign. Bailing out\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed device_callsign: %d bytes\n", length);
|
||||
}
|
||||
if (uncompressed.which_payload_variant == meshtastic_TAKPacket_chat_tag) {
|
||||
auto length = unishox2_decompress_simple(t->payload_variant.chat.message, strlen(t->payload_variant.chat.message),
|
||||
uncompressed.payload_variant.chat.message);
|
||||
auto length = unishox2_decompress_lines(t->payload_variant.chat.message, strlen(t->payload_variant.chat.message),
|
||||
uncompressed.payload_variant.chat.message,
|
||||
sizeof(uncompressed.payload_variant.chat.message) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompression overflowed chat.message. Bailing out\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed chat message: %d bytes\n", length);
|
||||
|
||||
if (t->payload_variant.chat.has_to) {
|
||||
uncompressed.payload_variant.chat.has_to = true;
|
||||
length = unishox2_decompress_simple(t->payload_variant.chat.to, strlen(t->payload_variant.chat.to),
|
||||
uncompressed.payload_variant.chat.to);
|
||||
length = unishox2_decompress_lines(t->payload_variant.chat.to, strlen(t->payload_variant.chat.to),
|
||||
uncompressed.payload_variant.chat.to,
|
||||
sizeof(uncompressed.payload_variant.chat.to) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompression overflowed chat.to. Bailing out\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed chat to: %d bytes\n", length);
|
||||
}
|
||||
|
||||
if (t->payload_variant.chat.has_to_callsign) {
|
||||
uncompressed.payload_variant.chat.has_to_callsign = true;
|
||||
length =
|
||||
unishox2_decompress_simple(t->payload_variant.chat.to_callsign, strlen(t->payload_variant.chat.to_callsign),
|
||||
uncompressed.payload_variant.chat.to_callsign);
|
||||
unishox2_decompress_lines(t->payload_variant.chat.to_callsign, strlen(t->payload_variant.chat.to_callsign),
|
||||
uncompressed.payload_variant.chat.to_callsign,
|
||||
sizeof(uncompressed.payload_variant.chat.to_callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompression overflowed chat.to_callsign. Bailing out\n");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed chat to_callsign: %d bytes\n", length);
|
||||
}
|
||||
}
|
||||
@@ -148,4 +191,4 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast
|
||||
service.sendToPhone(decompressedCopy);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
#include "configuration.h"
|
||||
#include "gps/GeoCoord.h"
|
||||
#include "main.h"
|
||||
#include "mesh/compression/unishox2.h"
|
||||
#include "meshtastic/atak.pb.h"
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
|
||||
extern "C" {
|
||||
#include "mesh/compression/unishox2.h"
|
||||
#include <Throttle.h>
|
||||
}
|
||||
|
||||
@@ -255,10 +255,12 @@ meshtastic_MeshPacket *PositionModule::allocAtakPli()
|
||||
.course = static_cast<uint16_t>(localPosition.ground_track),
|
||||
}}};
|
||||
|
||||
auto length = unishox2_compress_simple(owner.long_name, strlen(owner.long_name), takPacket.contact.device_callsign);
|
||||
auto length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.device_callsign,
|
||||
sizeof(takPacket.contact.device_callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
LOG_DEBUG("Uncompressed device_callsign '%s' - %d bytes\n", owner.long_name, strlen(owner.long_name));
|
||||
LOG_DEBUG("Compressed device_callsign '%s' - %d bytes\n", takPacket.contact.device_callsign, length);
|
||||
length = unishox2_compress_simple(owner.long_name, strlen(owner.long_name), takPacket.contact.callsign);
|
||||
length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.callsign,
|
||||
sizeof(takPacket.contact.callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
mp->decoded.payload.size =
|
||||
pb_encode_to_bytes(mp->decoded.payload.bytes, sizeof(mp->decoded.payload.bytes), &meshtastic_TAKPacket_msg, &takPacket);
|
||||
return mp;
|
||||
|
||||
Reference in New Issue
Block a user