Router: size the fit check from the decoded Data (#11018)
This commit is contained in:
co-authored by
GitHub
parent
f7fd058308
commit
f52d7753ad
+15
-15
@@ -452,7 +452,7 @@ void Router::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Rout
|
||||
}
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI) && !(MESHTASTIC_EXCLUDE_XEDDSA)
|
||||
bool checkXeddsaReceivePolicy(meshtastic_MeshPacket *p, size_t encodedDataSize)
|
||||
bool checkXeddsaReceivePolicy(meshtastic_MeshPacket *p)
|
||||
{
|
||||
// Only a signature we verify below may mark this packet signed; never trust an inbound flag.
|
||||
p->xeddsa_signed = false;
|
||||
@@ -483,17 +483,17 @@ bool checkXeddsaReceivePolicy(meshtastic_MeshPacket *p, size_t encodedDataSize)
|
||||
return false;
|
||||
} else {
|
||||
// Truly unsigned (signature size 0) - only reject the class a signing node always signs: a
|
||||
// non-PKI broadcast whose signed encoding would still fit the LoRa frame. encodedDataSize is
|
||||
// the size of the encoded Data exactly as the sender built it (or 0 to size p->decoded
|
||||
// canonically); with no signature field present it is the unsigned base, and adding
|
||||
// XEDDSA_SIGNATURE_FIELD_BYTES mirrors the sender-side signedDataFits() gate per packet,
|
||||
// whatever fields the Data carried. Unicast/PKI packets and broadcasts too big to carry a
|
||||
// signature are never signed, so they must not be hard-failed here even for a known signer.
|
||||
// non-PKI broadcast whose signed encoding would still fit the LoRa frame. Size p->decoded
|
||||
// canonically so this counts the same fields the sender's signedDataFits() gate counted;
|
||||
// adding XEDDSA_SIGNATURE_FIELD_BYTES to that unsigned base mirrors it exactly, whatever
|
||||
// fields the Data carried. Unicast/PKI packets and broadcasts too big to carry a signature
|
||||
// are never signed, so they must not be hard-failed here even for a known signer.
|
||||
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->from);
|
||||
if (node && nodeInfoLiteHasXeddsaSigned(node) && !p->pki_encrypted && isBroadcast(p->to)) {
|
||||
if (encodedDataSize == 0 && !pb_get_encoded_size(&encodedDataSize, &meshtastic_Data_msg, &p->decoded))
|
||||
size_t canonicalSize;
|
||||
if (!pb_get_encoded_size(&canonicalSize, &meshtastic_Data_msg, &p->decoded))
|
||||
return true; // can't size it; never drop on a sizing failure
|
||||
if (encodedDataSize + XEDDSA_SIGNATURE_FIELD_BYTES + MESHTASTIC_HEADER_LENGTH <= MAX_LORA_PAYLOAD_LEN) {
|
||||
if (canonicalSize + XEDDSA_SIGNATURE_FIELD_BYTES + MESHTASTIC_HEADER_LENGTH <= MAX_LORA_PAYLOAD_LEN) {
|
||||
LOG_WARN("Dropping unsigned broadcast from 0x%08x that previously signed", p->from);
|
||||
return false;
|
||||
}
|
||||
@@ -621,17 +621,17 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
|
||||
if (decrypted) {
|
||||
// parsing was successful
|
||||
p->channel = chIndex; // change to store the index instead of the hash
|
||||
if (p->decoded.has_bitfield)
|
||||
p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK;
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI) && !(MESHTASTIC_EXCLUDE_XEDDSA)
|
||||
// rawSize is the size of the encoded Data exactly as the sender built it (the PKI branch's
|
||||
// MESHTASTIC_PKC_OVERHEAD subtraction preserves that, and PKI packets are unicast so the
|
||||
// downgrade predicate ignores them anyway).
|
||||
if (!checkXeddsaReceivePolicy(p, rawSize))
|
||||
// Runs before the bitfield merge below: that merge can set want_response, adding wire bytes
|
||||
// the sender never encoded and skewing the policy's sizing of p->decoded.
|
||||
if (!checkXeddsaReceivePolicy(p))
|
||||
return DecodeState::DECODE_FAILURE;
|
||||
#endif
|
||||
|
||||
if (p->decoded.has_bitfield)
|
||||
p->decoded.want_response |= p->decoded.bitfield & BITFIELD_WANT_RESPONSE_MASK;
|
||||
|
||||
/* Not actually ever used.
|
||||
// Decompress if needed. jm
|
||||
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||
|
||||
Reference in New Issue
Block a user