Cappend number of flows per Netflow v9 packet to avoid infinite loop
This commit is contained in:
parent
f97385e3bc
commit
bcb4902fdb
@ -671,7 +671,7 @@ bool process_netflow_v9_template(uint8_t* pkt, size_t len, uint32_t source_id, c
|
|||||||
|
|
||||||
uint32_t total_size = 0;
|
uint32_t total_size = 0;
|
||||||
|
|
||||||
std::vector<peer_nf9_record_t> template_records_map;
|
std::vector<peer_nf9_record_t> template_records_map;
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
if (offset >= len) {
|
if (offset >= len) {
|
||||||
logger << log4cpp::Priority::ERROR << "Short Netflow v9 flowset template";
|
logger << log4cpp::Priority::ERROR << "Short Netflow v9 flowset template";
|
||||||
@ -1820,8 +1820,8 @@ bool process_netflow_packet_v10(uint8_t* packet, uint32_t len, const std::string
|
|||||||
|
|
||||||
ipfix_data_packet_number++;
|
ipfix_data_packet_number++;
|
||||||
|
|
||||||
if (process_netflow_v10_data(packet + offset, flowset_len, nf10_hdr, source_id,
|
if (!process_netflow_v10_data(packet + offset, flowset_len, nf10_hdr, source_id,
|
||||||
client_addres_in_string_format, client_ipv4_address) != 0) {
|
client_addres_in_string_format, client_ipv4_address)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1844,30 +1844,27 @@ bool process_netflow_packet_v9(uint8_t* packet, uint32_t len, std::string& clien
|
|||||||
nf9_flowset_header_common_t* flowset = nullptr;
|
nf9_flowset_header_common_t* flowset = nullptr;
|
||||||
|
|
||||||
if (len < sizeof(*nf9_hdr)) {
|
if (len < sizeof(*nf9_hdr)) {
|
||||||
logger << log4cpp::Priority::ERROR << "Short netflow v9 header";
|
logger << log4cpp::Priority::ERROR << "Short Netflow v9 header";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t count = ntohs(nf9_hdr->c.flows);
|
uint32_t flowset_count_total = ntohs(nf9_hdr->c.flows);
|
||||||
uint32_t source_id = ntohl(nf9_hdr->source_id);
|
|
||||||
|
|
||||||
|
// Limit reasonable number of flow sets per packet
|
||||||
|
if (flowset_count_total > flowsets_per_packet_maximum_number) {
|
||||||
|
logger << log4cpp::Priority::ERROR << "We have so many flowsets inside Netflow v9 packet: " << flowset_count_total
|
||||||
|
<< " Agent IP:" << client_addres_in_string_format;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t source_id = ntohl(nf9_hdr->source_id);
|
||||||
// logger<< log4cpp::Priority::INFO<<"Template source id: "<<source_id;
|
// logger<< log4cpp::Priority::INFO<<"Template source id: "<<source_id;
|
||||||
|
|
||||||
uint32_t offset = sizeof(*nf9_hdr);
|
uint32_t offset = sizeof(*nf9_hdr);
|
||||||
uint32_t total_flows = 0;
|
|
||||||
|
|
||||||
uint64_t flowset_number = 0;
|
// logger<< log4cpp::Priority::INFO<< "Total flowsets " << flowset_count_total;
|
||||||
|
|
||||||
for (uint32_t i = 0;; i++) {
|
|
||||||
flowset_number++;
|
|
||||||
|
|
||||||
// We limit number of flow sets in packet and also use it for infinite loop prevention
|
|
||||||
if (flowset_number > flowsets_per_packet_maximum_number) {
|
|
||||||
logger << log4cpp::Priority::ERROR
|
|
||||||
<< "Infinite loop prevention triggered or we have so many flowsets inside Netflow v9 packet";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (uint32_t flowset_number = 0; flowset_number < flowset_count_total; flowset_number++) {
|
||||||
/* Make sure we don't run off the end of the flow */
|
/* Make sure we don't run off the end of the flow */
|
||||||
if (offset >= len) {
|
if (offset >= len) {
|
||||||
logger << log4cpp::Priority::ERROR
|
logger << log4cpp::Priority::ERROR
|
||||||
@ -1888,8 +1885,6 @@ bool process_netflow_packet_v9(uint8_t* packet, uint32_t len, std::string& clien
|
|||||||
* handlers below.
|
* handlers below.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint64_t flowset_number = 0;
|
|
||||||
|
|
||||||
if (offset + flowset_len > len) {
|
if (offset + flowset_len > len) {
|
||||||
logger << log4cpp::Priority::ERROR << "We tried to read from address outside Netflow's packet flowset agent IP: "
|
logger << log4cpp::Priority::ERROR << "We tried to read from address outside Netflow's packet flowset agent IP: "
|
||||||
<< client_addres_in_string_format << " flowset number: " << flowset_number
|
<< client_addres_in_string_format << " flowset number: " << flowset_number
|
||||||
@ -1932,6 +1927,8 @@ bool process_netflow_packet_v9(uint8_t* packet, uint32_t len, std::string& clien
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This logic will stop processing if we've reached end of flow set setction before reading all flow sets
|
||||||
|
// It's not reliable to use alone because we may have garbadge at the end of packet. That's why we have loop over number of flowset records as main condition.
|
||||||
offset += flowset_len;
|
offset += flowset_len;
|
||||||
if (offset == len) {
|
if (offset == len) {
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user