From 5164a29603fff9dd445b7660a35090989f005000 Mon Sep 17 00:00:00 2001 From: Pavel Odintsov Date: Fri, 13 Dec 2024 02:08:40 +0300 Subject: [PATCH] Fixed DoS vulnerability in sFlow v5 plugin which caused crash of FastNetMon with specially crafted packet. Reported by Evgeny Shtanov aka @Klavishnik --- src/libsflow/libsflow.hpp | 3 +++ src/sflow_plugin/sflow_collector.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/libsflow/libsflow.hpp b/src/libsflow/libsflow.hpp index 0e78806f..f32a0388 100644 --- a/src/libsflow/libsflow.hpp +++ b/src/libsflow/libsflow.hpp @@ -15,6 +15,9 @@ // We need it for sanity checks const uint32_t max_udp_packet_size = 65535; +// We need to limit number of samples by reasonable number +const int32_t max_sflow_sample_number = 256; + enum class sflow_sample_type_t : unsigned int { FLOW_SAMPLE = 1, COUNTER_SAMPLE = 2, diff --git a/src/sflow_plugin/sflow_collector.cpp b/src/sflow_plugin/sflow_collector.cpp index 80a11a6b..98754fa8 100644 --- a/src/sflow_plugin/sflow_collector.cpp +++ b/src/sflow_plugin/sflow_collector.cpp @@ -515,6 +515,16 @@ void parse_sflow_v5_packet(const uint8_t* payload_ptr, unsigned int payload_leng return; } + // As we're going to allocate memory using this value as number of elements + // we need to ensure that we capped it by reasonable value + if (sflow_header_accessor.get_datagram_samples_count() > max_sflow_sample_number) { + logger << log4cpp::Priority::ERROR << plugin_log_prefix + << "Number of sFlow samples in packet " << sflow_header_accessor.get_datagram_samples_count() + << " exceeds allowed maximum value " << max_sflow_sample_number; + sflow_bad_packets++; + return; + } + std::vector samples_vector; samples_vector.reserve(sflow_header_accessor.get_datagram_samples_count());