Tun: reject packets with bad length

Those packets are probably packets truncated because the buffer is not
large enough.
This commit is contained in:
Théophile Bastian 2020-06-16 20:24:59 +02:00
parent 79dbf23784
commit 0b8cf0edc1
5 changed files with 19 additions and 7 deletions

View File

@ -76,13 +76,18 @@ size_t UdpVpn::read_from_tun(char* buffer, size_t len) {
}
size_t UdpVpn::read_from_tun(TunnelledPacket& packet) {
size_t nread =
read_from_tun(packet.get_payload(), packet.get_payload_space());
size_t payload_space = packet.get_payload_space();
size_t nread = read_from_tun(packet.get_payload(), payload_space);
packet.set_payload_size(nread);
if(!packet.parse_as_ipv6()) {
debugf("Ignoring packet with invalid header\n");
return 0;
}
if(nread != packet.get_ipv6_header().packet_length()) {
debugf("Ignoring packet with bad size (expected %d, got %d, buffer %d)\n",
packet.get_ipv6_header().packet_length(), nread, payload_space);
return 0;
}
return nread;
}

View File

@ -31,7 +31,7 @@ VpnPacketTLV VpnPacket::first_tlv() {
}
size_t VpnPacket::get_tunnelled_mtu(size_t udp_mtu) {
return udp_mtu - VPN_HEADER_BYTES - TLV_HEADER_BYTES;
return udp_mtu - OUTER_HEADERS_BYTES - VPN_HEADER_BYTES - TLV_HEADER_BYTES;
}
uint32_t VpnPacket::get_seqno() const {
@ -102,6 +102,12 @@ void VpnPacketTLV::set_payload_size(uint16_t size) {
_packet.increase_payload_size(size - old_size);
}
uint16_t VpnPacketTLV::get_payload_space() const {
return _packet.get_payload_space()
- _packet.get_payload_size()
+ get_payload_size();
}
VpnPacket::PayloadType VpnPacketTLV::get_type() const {
return (VpnPacket::PayloadType)(*(uint8_t*)(get_data()));
}

View File

@ -159,10 +159,7 @@ class VpnPacketTLV {
/// Set the current payload size
void set_payload_size(uint16_t size);
/// Get the total available raw data space
uint16_t get_payload_space() const {
return _packet.get_payload_space()
- _packet.get_payload_size()
- get_payload_size(); }
uint16_t get_payload_space() const;
/// Get a pointer to the raw data (const version)
const char* get_data() const {

View File

@ -15,5 +15,6 @@ bool parse_ipv6_header(const char* data, size_t len, IPv6Header& header) {
memcpy(&(header.source), data + 8, 16);
memcpy(&(header.dest), data + 24, 16);
header.payload_length = ntohs(*(uint16_t*)(data + 4));
return true;
}

View File

@ -5,6 +5,9 @@
struct IPv6Header {
in6_addr source;
in6_addr dest;
uint16_t payload_length;
uint16_t packet_length() const { return payload_length + 40; }
};
/** Parse an IPv6 header, filling `header`. Returns `true` on success. */