Tun: reject packets with bad length
Those packets are probably packets truncated because the buffer is not large enough.
This commit is contained in:
parent
79dbf23784
commit
0b8cf0edc1
5 changed files with 19 additions and 7 deletions
|
@ -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 UdpVpn::read_from_tun(TunnelledPacket& packet) {
|
||||||
size_t nread =
|
size_t payload_space = packet.get_payload_space();
|
||||||
read_from_tun(packet.get_payload(), packet.get_payload_space());
|
size_t nread = read_from_tun(packet.get_payload(), payload_space);
|
||||||
packet.set_payload_size(nread);
|
packet.set_payload_size(nread);
|
||||||
if(!packet.parse_as_ipv6()) {
|
if(!packet.parse_as_ipv6()) {
|
||||||
debugf("Ignoring packet with invalid header\n");
|
debugf("Ignoring packet with invalid header\n");
|
||||||
return 0;
|
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;
|
return nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ VpnPacketTLV VpnPacket::first_tlv() {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t VpnPacket::get_tunnelled_mtu(size_t udp_mtu) {
|
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 {
|
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);
|
_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 {
|
VpnPacket::PayloadType VpnPacketTLV::get_type() const {
|
||||||
return (VpnPacket::PayloadType)(*(uint8_t*)(get_data()));
|
return (VpnPacket::PayloadType)(*(uint8_t*)(get_data()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,10 +159,7 @@ class VpnPacketTLV {
|
||||||
/// Set the current payload size
|
/// Set the current payload size
|
||||||
void set_payload_size(uint16_t size);
|
void set_payload_size(uint16_t size);
|
||||||
/// Get the total available raw data space
|
/// Get the total available raw data space
|
||||||
uint16_t get_payload_space() const {
|
uint16_t get_payload_space() const;
|
||||||
return _packet.get_payload_space()
|
|
||||||
- _packet.get_payload_size()
|
|
||||||
- get_payload_size(); }
|
|
||||||
|
|
||||||
/// Get a pointer to the raw data (const version)
|
/// Get a pointer to the raw data (const version)
|
||||||
const char* get_data() const {
|
const char* get_data() const {
|
||||||
|
|
|
@ -15,5 +15,6 @@ bool parse_ipv6_header(const char* data, size_t len, IPv6Header& header) {
|
||||||
|
|
||||||
memcpy(&(header.source), data + 8, 16);
|
memcpy(&(header.source), data + 8, 16);
|
||||||
memcpy(&(header.dest), data + 24, 16);
|
memcpy(&(header.dest), data + 24, 16);
|
||||||
|
header.payload_length = ntohs(*(uint16_t*)(data + 4));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
struct IPv6Header {
|
struct IPv6Header {
|
||||||
in6_addr source;
|
in6_addr source;
|
||||||
in6_addr dest;
|
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. */
|
/** Parse an IPv6 header, filling `header`. Returns `true` on success. */
|
||||||
|
|
Loading…
Reference in a new issue