receive: require data packets to contain at least a full method header

Further lower the ampliciation factor by ignoring packets that are too
short to be a valid data packet.
This commit is contained in:
Matthias Schiffer 2024-12-29 21:27:49 +01:00
parent 1f233bee76
commit d03a0a1734
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
3 changed files with 16 additions and 8 deletions

View file

@ -467,7 +467,9 @@ static void configure_user(void) {
/** Initializes global configuration that depends on the configured methods */
static void configure_method_parameters(void) {
conf.overhead = 0;
conf.min_overhead = SIZE_MAX;
conf.max_overhead = 0;
conf.encrypt_headroom = 0;
conf.decrypt_headroom = 0;
@ -475,7 +477,8 @@ static void configure_method_parameters(void) {
for (i = 0; conf.methods[i].name; i++) {
const fastd_method_provider_t *provider = conf.methods[i].provider;
conf.overhead = max_size_t(conf.overhead, provider->overhead);
conf.min_overhead = min_size_t(conf.min_overhead, provider->overhead);
conf.max_overhead = max_size_t(conf.max_overhead, provider->overhead);
conf.encrypt_headroom = max_size_t(conf.encrypt_headroom, provider->encrypt_headroom);
conf.decrypt_headroom = max_size_t(conf.decrypt_headroom, provider->decrypt_headroom);
}
@ -669,7 +672,7 @@ static void configure_peers(bool dirs_only) {
/* Reserve one extra block of encrypt headroom for multiaf_tun targets */
size_t headroom =
max_size_t(conf.encrypt_headroom + sizeof(fastd_block128_t), conf.decrypt_headroom + conf.overhead);
max_size_t(conf.encrypt_headroom + sizeof(fastd_block128_t), conf.decrypt_headroom + conf.max_overhead);
ctx.max_buffer = alignto(
max_size_t(headroom + fastd_max_payload(ctx.max_mtu), MAX_HANDSHAKE_SIZE), sizeof(fastd_block128_t));
}

View file

@ -248,7 +248,8 @@ struct fastd_config {
fastd_string_stack_t *method_list; /**< The list of configured method names */
fastd_method_info_t *methods; /**< The list of configured methods */
size_t overhead; /**< The maximum overhead of all configured methods */
size_t min_overhead; /**< The minimum overhead of all configured methods */
size_t max_overhead; /**< The maximum overhead of all configured methods */
size_t encrypt_headroom; /**< The minimum space a configured methods needs a the beginning of a source buffer to
* encrypt */
size_t decrypt_headroom; /**< The minimum space a configured methods needs a the beginning of a source buffer to

View file

@ -228,16 +228,20 @@ static void handle_socket_receive(
fastd_handshake_handle(sock, local_addr, remote_addr, peer, buffer, has_control_header);
} else if (is_data_packet(packet_type)) {
if (!backoff_unknown(remote_addr)) {
pr_debug("unexpectedly received payload data from %I", remote_addr);
/* In theory, PACKET_DATA_COMPAT could also be a valid first byte for
* a future L2TPv3 extension, but as no such extensions exist and
* Linux is unlikely to just enable such extensions by default in
* the L2TP kernel implementation, we assume that suchs packets must
* be generated by a pre-v22 fastd version without L2TP support. */
unsigned flags = packet_type == PACKET_DATA_COMPAT ? 0 : FLAG_L2TP_SUPPORT;
if (buffer->len < conf.min_overhead) {
pr_debug("unexpectedly received short payload data from %I", remote_addr);
} else {
pr_debug("unexpectedly received payload data from %I, sending handshake", remote_addr);
conf.protocol->handshake_init(sock, local_addr, remote_addr, NULL, flags);
}
}
} else {
pr_debug("received packet with invalid type from %I", remote_addr);
}
@ -248,7 +252,7 @@ end_free:
/** Reads a packet from a socket */
void fastd_receive(fastd_socket_t *sock) {
size_t max_len = max_size_t(fastd_max_payload(ctx.max_mtu) + conf.overhead, MAX_HANDSHAKE_SIZE);
size_t max_len = max_size_t(fastd_max_payload(ctx.max_mtu) + conf.max_overhead, MAX_HANDSHAKE_SIZE);
fastd_buffer_t *buffer = fastd_buffer_alloc(max_len, conf.decrypt_headroom);
fastd_peer_address_t local_addr;
fastd_peer_address_t recvaddr;