remove(conf.c_str());
}
+TEST_CASE("Discovery Filter with Problem Config", "[df_problem_config]")
+{
+ // Checks a set of configs that previously caused
+ // a heap-use-after-free when initializing nodes
+
+ string conf("test_intf_ip.txt");
+ ofstream out_stream(conf.c_str());
+ out_stream << "config AnalyzeHost 10.0.0.0/24 -1\n"; // interface any
+ out_stream << "config AnalyzeHost 10.0.0.0/21 4\n"; // interface 4
+ out_stream << "config AnalyzeHost 192.8.8.0/24 -1\n"; // interface any
+ out_stream.close();
+
+
+ // Verifies the config loads with no issues - otherwise, ASAN
+ // will report leaks when constructing df below
+ DiscoveryFilter df(conf);
+
+ remove("test_intf_ip.txt");
+}
+
#endif
/*
* Adam Keeton
- * sf_ipvar.c
+ * sf_ipvar.cc
* 11/17/06
*
* Library for IP variables.
static SfIpRet sfvar_list_compare(sfip_node_t*, sfip_node_t*);
static inline void sfip_node_free(sfip_node_t*&);
-static inline void sfip_node_freelist(sfip_node_t*);
+static inline void sfip_node_freelist(sfip_node_t*&);
static inline sfip_var_t* _alloc_var()
{
if (var->value)
snort_free(var->value);
- if (var->mode == SFIP_LIST)
- {
- sfip_node_freelist(var->head);
- sfip_node_freelist(var->neg_head);
- }
- else if (var->mode == SFIP_TABLE)
- {
- // FIXIT-L SFIP_TABLE free unimplemented
- }
+ sfip_node_freelist(var->head);
+ sfip_node_freelist(var->neg_head);
snort_free(var);
}
{
if (status)
*status = SFIP_ARG_ERR;
- snort_free(ret);
+ sfip_node_free(ret);
return nullptr;
}
return;
if ( node->ip )
+ {
delete node->ip;
+ }
snort_free(node);
node = nullptr;
}
-static inline void sfip_node_freelist(sfip_node_t* root)
+static inline void sfip_node_freelist(sfip_node_t*& root)
{
sfip_node_t* node;
{
head = tail = node;
sfip_node_free(cur);
+ head->next = nullptr;
return true;
}
+
sfip_node_free(cur); // overlaps removed so that caller can insert the node
--count;
}
ret = (sfip_var_t*)snort_calloc(sizeof(*ret));
- ret->mode = var->mode;
ret->head = _sfvar_deep_copy_list(var->head);
ret->neg_head = _sfvar_deep_copy_list(var->neg_head);
ret->head_count = var->head_count;
dst->neg_head = merge_lists(dst->neg_head, copiedvar->neg_head, dst->neg_head_count,
copiedvar->neg_head_count, dst->neg_head_count);
+ // This needs to be snort_free rather than sfipvar_free since
+ // we don't want to free the nodes
snort_free(copiedvar);
return SFIP_SUCCESS;
}
// Adds the nodes in 'src' to the variable 'dst'
-// The mismatch of types is for ease-of-supporting Snort4 and
-// Snort6 simultaneously
+// The mismatch of types is for ease-of-supporting IPv4 and
+// IPv6 simultaneously
static SfIpRet sfvar_add_node(sfip_var_t* var, sfip_node_t* node, int negated)
{
- sfip_node_t* p;
- sfip_node_t* swp;
- sfip_node_t** head;
+ sfip_node_t* p = nullptr;
+ sfip_node_t* swp = nullptr;
+ sfip_node_t** head = nullptr;
uint32_t* count;
if (!var || !node)
return SFIP_ARG_ERR;
- // As of this writing, 11/20/06, nodes are always added to
- // the list, regardless of the mode (list or table).
-
if (negated)
{
head = &var->neg_head;
struct SfCidr;
}
-/* Selects which mode a given variable is using to
- * store and lookup IP addresses */
-typedef enum _modes
-{
- SFIP_LIST,
- SFIP_TABLE
-} MODES;
-
-/* Used by the "list" mode. A doubly linked list of SfIp objects. */
+/* A doubly linked list of SfIp objects. */
typedef struct _ip_node
{
- snort::SfCidr* ip;
-#define ip_addr ip; /* To ease porting Snort */
- struct _ip_node* next;
- int flags;
- int addr_flags; /* Flags used exclusively by Snort */
+ snort::SfCidr* ip = nullptr;
+ struct _ip_node* next = nullptr;
+ int flags = 0;
+ int addr_flags = 0;
+ /* Flags used exclusively by Snort */
/* Keeping these variables separate keeps
* this from stepping on Snort's toes. */
/* Should merge them later */
} sfip_node_t;
-/* An IP variable onkect */
+/* An IP variable object */
struct sfip_var_t
{
- /* Selects whether or not to use the list, the table,
- * or any other method added later */
- MODES mode;
-
/* Linked lists. Switch to something faster later */
sfip_node_t* head;
sfip_node_t* neg_head;