@@ -146,6 +146,14 @@ def onReceive(self, packet):
146146
147147 def _shouldFilterPacket (self , p ):
148148 """Given a packet, decode it and return true if it should be ignored"""
149+ # Packets received from the mesh are untrusted. IPv4 requires a
150+ # 20-byte header, and the protocol-specific fields below require the
151+ # first four bytes of the transport header. Without these checks a
152+ # truncated payload raises IndexError in the tunnel reader thread.
153+ if not isinstance (p , (bytes , bytearray )) or len (p ) < 20 :
154+ logger .warning ("Ignoring malformed IP tunnel packet" )
155+ return True
156+
149157 protocol = p [8 + 1 ]
150158 srcaddr = p [12 :16 ]
151159 destAddr = p [16 :20 ]
@@ -157,6 +165,9 @@ def _shouldFilterPacket(self, p):
157165 self .LOG_TRACE , f"Ignoring blacklisted protocol 0x{ protocol :02x} "
158166 )
159167 elif protocol == 0x01 : # ICMP
168+ if len (p ) < subheader + 4 :
169+ logger .warning ("Ignoring truncated ICMP tunnel packet" )
170+ return True
160171 icmpType = p [20 ]
161172 icmpCode = p [21 ]
162173 checksum = p [22 :24 ]
@@ -168,6 +179,9 @@ def _shouldFilterPacket(self, p):
168179 # pingback = p[:12]+p[16:20]+p[12:16]+p[20:]
169180 # tap.write(pingback)
170181 elif protocol == 0x11 : # UDP
182+ if len (p ) < subheader + 4 :
183+ logger .warning ("Ignoring truncated UDP tunnel packet" )
184+ return True
171185 srcport = readnet_u16 (p , subheader )
172186 destport = readnet_u16 (p , subheader + 2 )
173187 if destport in self .udpBlacklist :
@@ -176,6 +190,9 @@ def _shouldFilterPacket(self, p):
176190 else :
177191 logger .debug (f"forwarding udp srcport={ srcport } , destport={ destport } " )
178192 elif protocol == 0x06 : # TCP
193+ if len (p ) < subheader + 4 :
194+ logger .warning ("Ignoring truncated TCP tunnel packet" )
195+ return True
179196 srcport = readnet_u16 (p , subheader )
180197 destport = readnet_u16 (p , subheader + 2 )
181198 if destport in self .tcpBlacklist :
0 commit comments