Skip to content

Commit

Permalink
Fix: Issue where the spooler would reuse wrongly cached event, found
Browse files Browse the repository at this point in the history
	with the help of Jim Hranicky
  • Loading branch information
binf committed Mar 4, 2015
1 parent ce3c022 commit 0e3df2d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 38 deletions.
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
0. SUMMARY
------------------------------------------------------------------------------

Barnyard2 - version 2-1.13
Barnyard2 - version 2-1.14

This README contains some quick information about how to set up and
configure barnyard2 to ensure it works as it should.
Expand Down
2 changes: 1 addition & 1 deletion src/barnyard2.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
#define VER_MAJOR "2"
#define VER_MINOR "1"
#define VER_REVISION "14"
#define VER_BUILD "335"
#define VER_BUILD "336"

#define STD_BUF 1024

Expand Down
105 changes: 70 additions & 35 deletions src/spooler.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ int spoolerCloseWaldo(Waldo *);
int spoolerPacketCacheAdd(Spooler *, Packet *);
int spoolerPacketCacheClear(Spooler *);

int spoolerEventCachePush(Spooler *, uint32_t, void *);
EventRecordNode * spoolerEventCacheGetByEventID(Spooler *, uint32_t);
int spoolerEventCachePush(Spooler *, uint32_t, void *,uint32_t,uint32_t);
EventRecordNode * spoolerEventCacheGetByEventID(Spooler *, uint32_t,uint32_t);
EventRecordNode * spoolerEventCacheGetHead(Spooler *);
uint8_t spoolerEventCacheHeadUsed(Spooler *);
int spoolerEventCacheClean(Spooler *);
Expand Down Expand Up @@ -713,14 +713,17 @@ void spoolerProcessRecord(Spooler *spooler, int fire_output)
pc.total_unknown++;
}

/* convert event id once */
uint32_t event_id = 0x0000ffff & ntohl(((Unified2CacheCommon *)spooler->record.data)->event_id);
uint32_t event_second = ntohl( ((Unified2CacheCommon *)spooler->record.data)->event_second);


/* check if it's packet */
if (type == UNIFIED2_PACKET)
{
/* convert event id once */
uint32_t event_id = ntohl(((Unified2Packet *)spooler->record.data)->event_id);

/* check if there is a previously cached event that matches this event id */
ernCache = spoolerEventCacheGetByEventID(spooler, event_id);
ernCache = spoolerEventCacheGetByEventID(spooler, event_id,event_second);

/* allocate space for the packet and construct the packet header */
spooler->record.pkt = SnortAlloc(sizeof(Packet));
Expand Down Expand Up @@ -826,7 +829,7 @@ void spoolerProcessRecord(Spooler *spooler, int fire_output)
}

/* cache new data */
spoolerEventCachePush(spooler, type, spooler->record.data);
spoolerEventCachePush(spooler, type, spooler->record.data,event_id,event_second);
spooler->record.data = NULL;

/* waldo operations occur after the output plugins are called */
Expand Down Expand Up @@ -865,11 +868,13 @@ void spoolerProcessRecord(Spooler *spooler, int fire_output)
spoolerEventCacheClean(spooler);
}

int spoolerEventCachePush(Spooler *spooler, uint32_t type, void *data)
int spoolerEventCachePush(Spooler *spooler, uint32_t type, void *data,u_int32_t event_id,u_int32_t event_second)
{
EventRecordNode *ernNode;

DEBUG_WRAP(DebugMessage(DEBUG_SPOOLER,"Caching event...\n"););
DEBUG_WRAP(DebugMessage(DEBUG_SPOOLER,"[%s], Caching event id[%u] second[%u] \n",
__FUNCTION__,
event_id,
event_second););

/* allocate memory */
ernNode = (EventRecordNode *)SnortAlloc(sizeof(EventRecordNode));
Expand All @@ -878,6 +883,9 @@ int spoolerEventCachePush(Spooler *spooler, uint32_t type, void *data)
ernNode->used = 0;
ernNode->type = type;
ernNode->data = data;

ernNode->event_id = event_id;
ernNode->event_second = event_second;

/* add new events to the front of the cache */
ernNode->next = spooler->event_cache;
Expand All @@ -890,14 +898,18 @@ int spoolerEventCachePush(Spooler *spooler, uint32_t type, void *data)
return 0;
}

EventRecordNode *spoolerEventCacheGetByEventID(Spooler *spooler, uint32_t event_id)
EventRecordNode *spoolerEventCacheGetByEventID(Spooler *spooler,uint32_t event_id,uint32_t event_second)
{
EventRecordNode *ernCurrent = spooler->event_cache;

while (ernCurrent != NULL)
{
if ( ntohl(((Unified2EventCommon *)ernCurrent->data)->event_id) == event_id )
if ( (ernCurrent->event_id == event_id) &&
(ernCurrent->event_second == event_second))
{
ernCurrent->time_used++;
DEBUG_WRAP(DebugMessage(DEBUG_SPOOLER,"[%s], Using cached event[%d] event second [%d] \n",
__FUNCTION__,event_id,event_second););
return ernCurrent;
}

Expand Down Expand Up @@ -928,51 +940,74 @@ int spoolerEventCacheClean(Spooler *spooler)
EventRecordNode *ernCurrent = NULL;
EventRecordNode *ernPrev = NULL;
EventRecordNode *ernNext = NULL;
EventRecordNode *ernCandidate = NULL;
EventRecordNode *ernCandidateNext = NULL;
EventRecordNode *ernCandidatePrev = NULL;

if (spooler == NULL || spooler->event_cache == NULL )
return 1;

ernPrev = spooler->event_cache;
ernCurrent = spooler->event_cache;

while (ernCurrent != NULL && spooler->events_cached > barnyard2_conf->event_cache_size )
if(spooler->events_cached > barnyard2_conf->event_cache_size)
{
ernNext = ernCurrent->next;
while (ernCurrent != NULL)
{
ernNext = ernCurrent->next;
if(ernCurrent->used == 1 && ernCurrent->time_used >=1)
{
ernCandidateNext = ernNext;
ernCandidatePrev = ernPrev;
ernCandidate=ernCurrent;
}

if(ernCurrent != NULL)
{
ernPrev = ernCurrent;
}

ernCurrent = ernNext;
}

if ( ernCurrent->used == 1 )
{
if ( ernCandidate != NULL)
{
/* Delete from list */
if (ernCurrent == spooler->event_cache)
if (ernCandidate == spooler->event_cache)
{
spooler->event_cache = ernNext;
spooler->event_cache = NULL;
}
else
else
{
ernPrev->next = ernNext;
ernCandidatePrev->next = ernCandidateNext;
}

spooler->events_cached--;

if(ernCurrent->data != NULL)
DEBUG_WRAP(DebugMessage(DEBUG_SPOOLER,"[%s],Event currently cached [%d] Purging cached event[%d] event second [%d]\n",
__FUNCTION__,
spooler->events_cached,
ernCandidate->event_id,
ernCandidate->event_second););

spooler->events_cached--;

if(ernCandidate->data != NULL)
{
free(ernCurrent->data);
free(ernCandidate->data);
}

if(ernCurrent != NULL)
if(ernCandidate != NULL)
{
free(ernCurrent);
free(ernCandidate);
}
}

if(ernCurrent != NULL)
}
else
{
ernPrev = ernCurrent;
DEBUG_WRAP(DebugMessage(DEBUG_SPOOLER,"[%s],Can't find a purge candidate in event cache, oddness cached event [%d]!! \n",
__FUNCTION__,
spooler->events_cached););
}

ernCurrent = ernNext;

}

}
return 0;
}

Expand Down Expand Up @@ -1002,7 +1037,7 @@ void spoolerEventCacheFlush(Spooler *spooler)
}

spooler->event_cache = NULL;

spooler->events_cached = 0;
return;
}

Expand Down
5 changes: 4 additions & 1 deletion src/spooler.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ typedef struct _EventRecordNode
uint32_t type; /* type of event stored */
void *data; /* unified2 event (eg IPv4, IPV6, MPLS, etc) */
uint8_t used; /* has the event be retrieved */

uint32_t time_used; /* time it has fired */
uint32_t event_id; /* extracted from event original */
uint32_t event_second; /* extracted from event originale */

struct _EventRecordNode *next; /* reference to next event record */
} EventRecordNode;

Expand Down
11 changes: 11 additions & 0 deletions src/unified2.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,17 @@ typedef struct Unified2IDSEventIPv6_legacy

////////////////////-->LEGACY

/*
** Smaller subset of feature common across event,packet and extradata
**
**
*/
typedef struct _Unified2CacheCommon
{
uint32_t sensor_id;
uint32_t event_id;
uint32_t event_second;
} Unified2CacheCommon;

/*
** The Unified2EventCommon structure is the common structure that occurs
Expand Down

0 comments on commit 0e3df2d

Please sign in to comment.