From: Jeff Lucovsky Date: Mon, 29 Mar 2021 12:28:50 +0000 (-0400) Subject: detect/threshold: Function to deep-copy thresh obj X-Git-Tag: suricata-5.0.7~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f38bc87d119946daef7cb533d7a23b632f3ed1d;p=thirdparty%2Fsuricata.git detect/threshold: Function to deep-copy thresh obj This commit adds a function to make a deep copy of a DetectThresholdData object. The function is used when parsing threshold.config items to make a one-time object and then add copies as needed. (cherry picked from commit e873632a2811be4cd370336d43fcc5619bcd28e2) --- diff --git a/src/detect-threshold.c b/src/detect-threshold.c index eeef1c3595..2567453af9 100644 --- a/src/detect-threshold.c +++ b/src/detect-threshold.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2020 Open Information Security Foundation +/* Copyright (C) 2007-2021 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -277,6 +277,53 @@ static void DetectThresholdFree(void *de_ptr) } } +/** + * \brief Make a deep-copy of an extant DetectTHresholdData object. + * + * \param de pointer to DetectThresholdData + */ +DetectThresholdData *DetectThresholdDataCopy(DetectThresholdData *de) +{ + DetectThresholdData *new_de = SCCalloc(1, sizeof(DetectThresholdData)); + if (unlikely(new_de == NULL)) + return NULL; + + *new_de = *de; + new_de->addrs.ipv4_head = NULL; + new_de->addrs.ipv6_head = NULL; + + for (DetectAddress *last = NULL, *tmp_ad = de->addrs.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) { + DetectAddress *n_addr = DetectAddressCopy(tmp_ad); + if (n_addr == NULL) + goto error; + if (last == NULL) { + new_de->addrs.ipv4_head = n_addr; + } else { + last->next = n_addr; + n_addr->prev = last; + } + last = n_addr; + } + for (DetectAddress *last = NULL, *tmp_ad = de->addrs.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) { + DetectAddress *n_addr = DetectAddressCopy(tmp_ad); + if (n_addr == NULL) + goto error; + if (last == NULL) { + new_de->addrs.ipv6_head = n_addr; + } else { + last->next = n_addr; + n_addr->prev = last; + } + last = n_addr; + } + + return new_de; + +error: + DetectThresholdFree(new_de); + return NULL; +} + /* * ONLY TESTS BELOW THIS COMMENT */ diff --git a/src/detect-threshold.h b/src/detect-threshold.h index 534a6eb4ae..8b410e0148 100644 --- a/src/detect-threshold.h +++ b/src/detect-threshold.h @@ -86,6 +86,7 @@ typedef struct DetectThresholdEntry_ { */ void DetectThresholdRegister(void); +DetectThresholdData *DetectThresholdDataCopy(DetectThresholdData *); /** * This function registers unit tests for Threshold