TrafficManagement: gate role/NodeInfo cache writes on signer authenticity (#11048)
* TrafficManagement: gate role/NodeInfo cache writes on signer authenticity The tier-3 role cache and the PSRAM NodeInfo response cache were updated from any received NodeInfo with no authenticity check, so a spoofed NodeInfo could set a node's cached role (granting dedup exceptions) or poison the cached user served in direct responses. Skip both cache writes when a known signer's NodeInfo arrives unsigned, matching the identity-update gate on the direct-response path. * TrafficManagement: hoist shared NodeInfo signer lookup Compute the sender node lookup and unauthenticated-signer check once per NodeInfo packet and reuse it for both the cache-refresh gate and the direct-response identity gate, avoiding a second O(N) getMeshNode scan. --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
co-authored by
GitHub
Ben Meadors
parent
6e0e9c174d
commit
985b983f67
@@ -726,9 +726,16 @@ ProcessMessage TrafficManagementModule::handleReceived(const meshtastic_MeshPack
|
||||
return ProcessMessage::CONTINUE;
|
||||
}
|
||||
|
||||
// A known signer's NodeInfo arriving unsigned is unauthenticated (the sender is forgeable), so
|
||||
// it must not drive any cache or identity write below. Computed once here (getMeshNode is O(N))
|
||||
// and reused by both the cache-refresh and the direct-response identity path.
|
||||
const bool isNodeInfo = mp.decoded.portnum == meshtastic_PortNum_NODEINFO_APP;
|
||||
const meshtastic_NodeInfoLite *senderNode = isNodeInfo ? nodeDB->getMeshNode(getFrom(&mp)) : nullptr;
|
||||
const bool unauthenticatedSigner = senderNode && nodeInfoLiteHasXeddsaSigned(senderNode) && !mp.xeddsa_signed;
|
||||
|
||||
// Learn NodeInfo payloads into the dedicated PSRAM cache, and refresh the tier-3
|
||||
// role cache for any node we already track (keeps the dedup role exception current).
|
||||
if (mp.decoded.portnum == meshtastic_PortNum_NODEINFO_APP) {
|
||||
if (isNodeInfo && !unauthenticatedSigner) {
|
||||
cacheNodeInfoPacket(mp);
|
||||
updateCachedRoleFromNodeInfo(mp);
|
||||
}
|
||||
@@ -746,8 +753,7 @@ ProcessMessage TrafficManagementModule::handleReceived(const meshtastic_MeshPack
|
||||
if (shouldRespondToNodeInfo(&mp, true)) {
|
||||
// Unicast NodeInfo is never signed, so a known signer's identity claim here is
|
||||
// unauthenticated: don't overwrite its stored name. The cached response is unaffected.
|
||||
const meshtastic_NodeInfoLite *senderNode = nodeDB->getMeshNode(getFrom(&mp));
|
||||
const bool unauthenticatedSigner = senderNode && nodeInfoLiteHasXeddsaSigned(senderNode) && !mp.xeddsa_signed;
|
||||
// unauthenticatedSigner was computed above (this branch is NodeInfo-only).
|
||||
meshtastic_User requester = meshtastic_User_init_zero;
|
||||
if (!unauthenticatedSigner &&
|
||||
pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_User_msg, &requester)) {
|
||||
|
||||
Reference in New Issue
Block a user