snort: Updated to 2.9.8.0 with Quantum Insert patch included
Updated: rootfile
Updated: patch file
Signed-off-by: Matthias Fischer <matthias.fischer(a)ipfire.org>
---
config/rootfiles/common/snort | 2 +-
lfs/snort | 5 +-
.../stream_quantuminsert-snort-2.9.8.0.patch | 417 +++++++++++++++++++++
3 files changed, 421 insertions(+), 3 deletions(-)
create mode 100644 src/patches/stream_quantuminsert-snort-2.9.8.0.patch
diff --git a/config/rootfiles/common/snort b/config/rootfiles/common/snort
index 6dfcdfc..77208e8 100644
--- a/config/rootfiles/common/snort
+++ b/config/rootfiles/common/snort
@@ -27,7 +27,6 @@ usr/bin/u2spewfoo
#usr/include/snort/dynamic_output/snort_debug.h
#usr/include/snort/dynamic_output/stream_api.h
#usr/include/snort/dynamic_preproc
-#usr/include/snort/dynamic_preproc/appId.h
#usr/include/snort/dynamic_preproc/bitop.h
#usr/include/snort/dynamic_preproc/cpuclock.h
#usr/include/snort/dynamic_preproc/file_api.h
@@ -38,6 +37,7 @@ usr/bin/u2spewfoo
#usr/include/snort/dynamic_preproc/mpse_methods.h
#usr/include/snort/dynamic_preproc/obfuscation.h
#usr/include/snort/dynamic_preproc/packet_time.h
+#usr/include/snort/dynamic_preproc/perf_indicators.h
#usr/include/snort/dynamic_preproc/preprocids.h
#usr/include/snort/dynamic_preproc/profiler.h
#usr/include/snort/dynamic_preproc/segment_mem.h
diff --git a/lfs/snort b/lfs/snort
index 148f539..9b1d34d 100644
--- a/lfs/snort
+++ b/lfs/snort
@@ -24,7 +24,7 @@
include Config
-VER = 2.9.7.6
+VER = 2.9.8.0
THISAPP = snort-$(VER)
DL_FILE = $(THISAPP).tar.gz
@@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 65349f3272c4de5b3210f77f1f7ab0e6
+$(DL_FILE)_MD5 = 33a2ffd0daf3f60b81ab685848f95947
install : $(TARGET)
@@ -70,6 +70,7 @@ $(subst %,%_MD5,$(objects)) :
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
@rm -rf $(DIR_APP) $(DIR_SRC)/snort* && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+ cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/stream_quantuminsert-snort-2.9.8.0.patch
cd $(DIR_APP) && ./configure \
--prefix=/usr \
--sysconfdir=/etc/snort \
diff --git a/src/patches/stream_quantuminsert-snort-2.9.8.0.patch b/src/patches/stream_quantuminsert-snort-2.9.8.0.patch
new file mode 100644
index 0000000..f482de4
--- /dev/null
+++ b/src/patches/stream_quantuminsert-snort-2.9.8.0.patch
@@ -0,0 +1,417 @@
+--- src/preprocessors/Stream6/snort_stream_tcp.c Wed Nov 18 19:59:15 2015
++++ src/preprocessors/Stream6/snort_stream_tcp.c Fri Dec 11 13:39:41 2015
+@@ -48,6 +48,7 @@
+
+ #include <errno.h>
+ #include <assert.h>
++#include "Unified2_common.h"
+
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+@@ -202,6 +203,7 @@
+ #define EVENT_BAD_ACK 0x00008000
+ #define EVENT_DATA_AFTER_RST_RCVD 0x00010000
+ #define EVENT_WINDOW_SLAM 0x00020000
++#define EVENT_QUANTUM_INSERT 0x00040000
+
+ #define TF_NONE 0x0000
+ #define TF_WSCALE 0x0001
+@@ -386,6 +388,12 @@
+ // TBD move out of here since only used per packet?
+ StreamSegment* seglist_next; /* next queued segment to flush */
+
++ // Keep track of acked/purged segments, configurable with `max_track_old_segs`
++ StreamSegment *qi_seglist; /* first queued segment */
++ StreamSegment *qi_seglist_tail; /* last queued segment */
++ StreamSegment *qi_inserted_seg; /* the inconsistent segment, used for extra_data */
++ uint32_t qi_seg_count; /* number of current queued segments */
++
+ #ifdef DEBUG
+ int segment_ordinal;
+ #endif
+@@ -1402,6 +1410,7 @@
+ clone->max_consec_small_segs = master->max_consec_small_segs;
+ clone->max_consec_small_seg_size = master->max_consec_small_seg_size;
+ memcpy(clone->small_seg_ignore, master->small_seg_ignore, sizeof(master->small_seg_ignore));
++ clone->max_track_old_segs = master->max_track_old_segs;
+
+ config = (StreamConfig *) sfPolicyUserDataGet(stream_online_config, getParserPolicy( snort_conf ));
+ addStreamTcpPolicyToList( config->tcp_config, clone );
+@@ -1544,6 +1553,38 @@
+
+ #define STATIC_FP ((s5TcpPolicy->flags & STREAM_CONFIG_STATIC_FLUSHPOINTS)?1:0)
+
++static int GetQuantumPacket(void *ssn_ptr, uint8_t **buf, uint32_t *len, uint32_t *type)
++{
++ SessionControlBlock* scb = NULL;
++ TcpSession *tcpssn = NULL;
++ StreamTracker *listener = NULL;
++ StreamSegment *seg = NULL;
++
++ if (ssn_ptr == NULL)
++ return 0;
++
++ scb = (SessionControlBlock*) ssn_ptr;
++ if (scb->proto_specific_data)
++ tcpssn = (TcpSession *)scb->proto_specific_data->data;
++
++ if (tcpssn == NULL)
++ return 0;
++
++ listener = &tcpssn->client;
++ seg = listener->qi_inserted_seg;
++
++ if (seg == NULL)
++ return 0;
++
++ *buf = (uint8_t *)seg->data;
++ *len = seg->size;
++ *type = EVENT_INFO_GENERIC_DATA;
++
++ listener->qi_inserted_seg = NULL;
++
++ return 1;
++}
++
+ static void StreamParseTcpArgs(struct _SnortConfig *sc, StreamTcpConfig *config, char *args, StreamTcpPolicy *s5TcpPolicy)
+ {
+ char **toks;
+@@ -1571,6 +1612,10 @@
+ s5TcpPolicy->max_consec_small_seg_size = STREAM_DEFAULT_MAX_SMALL_SEG_SIZE;
+ s5TcpPolicy->log_asymmetric_traffic = false;
+
++ s5TcpPolicy->max_track_old_segs = STREAM_DEFAULT_TRACK_OLD_SEGS;
++ if (stream_api)
++ s5TcpPolicy->xtra_quantum_id = stream_api->reg_xtra_data_cb(GetQuantumPacket);
++
+ if(args != NULL && strlen(args) != 0)
+ {
+ toks = mSplit(args, ",", 0, &num_toks, 0);
+@@ -1859,6 +1904,39 @@
+ }
+ max_s_toks = 2;
+ }
++
++ else if(!strcasecmp(stoks[0], "max_track_old_segs"))
++ {
++ if(stoks[1])
++ {
++ long_val = SnortStrtol(stoks[1], &endPtr, 10);
++ if (errno == ERANGE)
++ {
++ errno = 0;
++ FatalError("%s(%d) => Invalid Max Track Old Segments. Integer parameter required.\n",
++ file_name, file_line);
++ }
++ s5TcpPolicy->max_track_old_segs = (uint32_t)long_val;
++ }
++
++ if (!stoks[1] || (endPtr == &stoks[1][0]))
++ {
++ FatalError("%s(%d) => Invalid Max Track Old Segments. Integer parameter required.\n",
++ file_name, file_line);
++ }
++
++ if (((long_val > STREAM_MAX_MAX_TRACK_OLD_SEGS) ||
++ (long_val < STREAM_MIN_MAX_TRACK_OLD_SEGS)) &&
++ (long_val != 0))
++ {
++ FatalError("%s(%d) => Invalid Max Track Old Segments."
++ " Must be 0 (disabled) or between %d and %d\n",
++ file_name, file_line,
++ STREAM_MAX_MAX_TRACK_OLD_SEGS, STREAM_MIN_MAX_TRACK_OLD_SEGS);
++ }
++ max_s_toks = 2;
++ }
++
+ else if (!strcasecmp(stoks[0], "small_segments"))
+ {
+ char **ptoks;
+@@ -2338,6 +2416,11 @@
+ LogMessage(" Maximum number of segs to queue per session: %d\n",
+ s5TcpPolicy->max_queued_segs);
+ }
++ if (s5TcpPolicy->max_track_old_segs != 0)
++ {
++ LogMessage(" Maximum number of old segs to track per session: %d\n",
++ s5TcpPolicy->max_track_old_segs);
++ }
+ if (s5TcpPolicy->flags)
+ {
+ LogMessage(" Options:\n");
+@@ -3055,6 +3138,22 @@
+ NULL); /* rule info ptr */
+ }
+
++static inline void EventQuantumInsert (StreamTcpPolicy *s5TcpPolicy)
++{
++ // if(!(s5TcpPolicy->flags & STREAM_CONFIG_ENABLE_ALERTS))
++ // return;
++
++ s5stats.events++;
++
++ SnortEventqAdd(GENERATOR_SPP_STREAM, /* GID */
++ STREAM_QUANTUM_INSERT, /* SID */
++ 1, /* rev */
++ 0, /* class */
++ 3, /* priority */
++ STREAM_QUANTUM_INSERT_STR, /* event msg */
++ NULL); /* rule info ptr */
++}
++
+ /*
+ * Utility functions for TCP stuff
+ */
+@@ -4133,6 +4232,10 @@
+ st->seglist = st->seglist_tail = st->seglist_next = NULL;
+ st->seg_count = st->flush_count = 0;
+ st->seg_bytes_total = st->seg_bytes_logical = 0;
++
++ st->qi_seg_count = 0;
++ DeleteSeglist(st->qi_seglist);
++ st->qi_seglist = st->qi_seglist_tail = st->qi_inserted_seg = NULL;
+ }
+
+ // purge_flushed_ackd():
+@@ -6113,6 +6216,69 @@
+ return NULL;
+ }
+
++static inline StreamSegment *FindOldSegment(StreamTracker *st, uint32_t pkt_seq)
++{
++ int32_t dist_head;
++ int32_t dist_tail;
++ StreamSegment *ss;
++
++ if (!st->qi_seglist)
++ return NULL;
++
++ dist_head = pkt_seq - st->qi_seglist->seq;
++ dist_tail = pkt_seq - st->qi_seglist_tail->seq;
++
++ if (dist_head <= dist_tail)
++ {
++ /* Start iterating at the head (left) */
++ for (ss = st->qi_seglist; ss; ss = ss->next)
++ {
++ if (SEQ_EQ(ss->seq, pkt_seq))
++ return ss;
++
++ if (SEQ_GEQ(ss->seq, pkt_seq))
++ break;
++ }
++ }
++ else
++ {
++ /* Start iterating at the tail (right) */
++ for (ss = st->qi_seglist_tail; ss; ss = ss->prev)
++ {
++ if (SEQ_EQ(ss->seq, pkt_seq))
++ return ss;
++
++ if (SEQ_LT(ss->seq, pkt_seq))
++ break;
++ }
++ }
++ return NULL;
++}
++
++static inline int CheckQuantumInsert(StreamTracker *listener,
++ TcpDataBlock *tdb,
++ Packet *p)
++{
++ int ret = 0;
++ StreamSegment* seg = NULL;
++
++ if (listener->seglist_tail && tdb->seq <= listener->seglist_tail->seq) {
++ seg = FindSegment(listener, tdb->seq);
++ }
++ if (seg == NULL && listener->qi_seglist_tail && tdb->seq <= listener->qi_seglist_tail->seq) {
++ seg = FindOldSegment(listener, tdb->seq);
++ }
++ if (seg) {
++ // compare smallest segment size
++ if (memcmp(p->data, seg->data, MIN(p->dsize, seg->size)) != 0) {
++ listener->qi_inserted_seg = seg;
++ SetExtraData(p, listener->tcp_policy->xtra_quantum_id);
++ ret |= EVENT_QUANTUM_INSERT;
++ }
++ }
++ return ret;
++}
++
+ void StreamTcpSessionClear(Packet *p)
+ {
+ SessionControlBlock *scb;
+@@ -7476,8 +7642,10 @@
+ {
+ if ( !(tcpssn->scb->ha_state.session_flags & SSNFLAG_STREAM_ORDER_BAD) )
+ {
+- if ( !SEQ_LEQ((tdb->seq + p->dsize), listener->r_nxt_ack) )
++ if ( !SEQ_LEQ((tdb->seq + p->dsize), listener->r_nxt_ack) ) {
+ tcpssn->scb->ha_state.session_flags |= SSNFLAG_STREAM_ORDER_BAD;
++ CheckQuantumInsert(listener, tdb, p);
++ }
+ }
+ ProcessTcpStream(listener, tcpssn, p, tdb, s5TcpPolicy);
+ }
+@@ -8162,6 +8330,9 @@
+
+ if (eventcode & EVENT_WINDOW_SLAM)
+ EventWindowSlam(s5TcpPolicy);
++
++ if (eventcode & EVENT_QUANTUM_INSERT)
++ EventQuantumInsert(s5TcpPolicy);
+ }
+
+ static inline void DisableInspection (SessionControlBlock *scb, Packet* p, char ignore)
+@@ -9195,6 +9366,10 @@
+ if ((p->tcph->th_flags != 0) || (s5TcpPolicy->policy == STREAM_POLICY_LINUX) || (s5TcpPolicy->policy == STREAM_POLICY_NOACK))
+ {
+ ProcessTcpData(p, listener, tcpssn, tdb, s5TcpPolicy);
++
++ if (listener->qi_inserted_seg)
++ eventcode |= EVENT_QUANTUM_INSERT;
++
+ //Check if all segments are received. Process FIN transition
+ if(checkFINTransitionStatus(p, listener))
+ process_fin = true;
+@@ -10144,8 +10319,46 @@
+ if ( st->seglist_next == seg )
+ st->seglist_next = NULL;
+
+- SegmentFree(seg);
+- st->seg_count--;
++ // Keep track of `max_track_old_segs` segments
++ if (st->tcp_policy->max_track_old_segs) {
++ StreamSegment* prev = st->qi_seglist_tail;
++ StreamSegment* new = seg;
++ if(prev)
++ {
++ new->next = prev->next;
++ new->prev = prev;
++ prev->next = new;
++ if (new->next)
++ new->next->prev = new;
++ else
++ st->qi_seglist_tail = new;
++ }
++ else
++ {
++ new->next = st->qi_seglist;
++ if(new->next)
++ new->next->prev = new;
++ else
++ st->qi_seglist_tail = new;
++ st->qi_seglist = new;
++ }
++
++ st->qi_seg_count++;
++ while (st->qi_seg_count > st->tcp_policy->max_track_old_segs) {
++ StreamSegment* old = st->qi_seglist;
++ st->qi_seglist = st->qi_seglist->next;
++ if (st->qi_seglist)
++ st->qi_seglist->prev = NULL;
++ if (st->qi_seglist == NULL)
++ st->qi_seglist_tail = NULL;
++ SegmentFree(old);
++ st->qi_seg_count--;
++ st->seg_count--;
++ }
++ } else {
++ SegmentFree(seg);
++ st->seg_count--;
++ }
+
+ return ret;
+ }
+--- src/preprocessors/Stream6/stream_common.h Wed Nov 18 19:59:15 2015
++++ src/preprocessors/Stream6/stream_common.h Fri Dec 11 13:41:15 2015
+@@ -69,6 +69,9 @@
+ #define STREAM_DEFAULT_CONSEC_SMALL_SEGS 0 /* disabled */
+ #define STREAM_MAX_CONSEC_SMALL_SEGS 2048 /* 2048 single byte packets without acks is alot */
+ #define STREAM_MIN_CONSEC_SMALL_SEGS 0 /* 0 means disabled */
++#define STREAM_DEFAULT_TRACK_OLD_SEGS 10 /* keep track of 10 old TCP segments */
++#define STREAM_MIN_MAX_TRACK_OLD_SEGS 0 /* 0 means disabled */
++#define STREAM_MAX_MAX_TRACK_OLD_SEGS 2048 /* history of 2048 segments should be enough */
+
+ #if defined(FEAT_OPEN_APPID)
+ #define MAX_APP_PROTOCOL_ID 4
+@@ -203,6 +206,10 @@
+
+ uint32_t max_consec_small_segs;
+ uint32_t max_consec_small_seg_size;
++
++ uint32_t max_track_old_segs;
++ uint32_t xtra_quantum_id;
++
+ char small_seg_ignore[MAX_PORTS/8];
+ bool log_asymmetric_traffic;
+
+--- src/sfutil/Unified2_common.h Wed Nov 18 19:59:15 2015
++++ src/sfutil/Unified2_common.h Fri Dec 11 13:42:17 2015
+@@ -193,7 +193,8 @@
+ EVENT_INFO_HTTP_HOSTNAME,
+ EVENT_INFO_IPV6_SRC,
+ EVENT_INFO_IPV6_DST,
+- EVENT_INFO_JSNORM_DATA
++ EVENT_INFO_JSNORM_DATA,
++ EVENT_INFO_GENERIC_DATA
+ }EventInfoEnum;
+
+ typedef enum _EventDataType
+--- src/generators.h Wed Nov 18 19:59:14 2015
++++ src/generators.h Fri Dec 11 13:12:12 2015
+@@ -438,6 +438,7 @@
+ #define DNS_EVENT_OBSOLETE_TYPES 1
+ #define DNS_EVENT_EXPERIMENTAL_TYPES 2
+ #define DNS_EVENT_RDATA_OVERFLOW 3
++#define STREAM_QUANTUM_INSERT 21
+
+ #define GENERATOR_SKYPE 132
+
+@@ -592,6 +593,7 @@
+ #define STREAM_DATA_AFTER_RST_RCVD_STR "Data sent on stream after TCP Reset received"
+ #define STREAM_WINDOW_SLAM_STR "TCP window closed before receiving data"
+ #define STREAM_NO_3WHS_STR "TCP session without 3-way handshake"
++#define STREAM_QUANTUM_INSERT_STR "Possible Quantum Insert"
+
+ #define STREAM_INTERNAL_EVENT_STR ""
+
+--- tools/u2openappid/u2openappid.c Thu Apr 23 19:28:11 2015
++++ tools/u2openappid/u2openappid.c Fri Dec 11 13:43:55 2015
+@@ -296,6 +296,11 @@
+ len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
+ break;
+
++ case EVENT_INFO_GENERIC_DATA:
++ printf("Generic Data:\n");
++ LogBuffer(record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), len);
++ break;
++
+ case EVENT_INFO_SMTP_FILENAME:
+ printf("SMTP Attachment Filename: %.*s\n",
+ len,record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
+--- tools/u2spewfoo/u2spewfoo.c Thu Apr 23 19:28:11 2015
++++ tools/u2spewfoo/u2spewfoo.c Fri Dec 11 13:45:27 2015
+@@ -43,6 +43,8 @@
+
+ #include "Unified2_common.h"
+
++static void LogBuffer (const uint8_t* p, unsigned n);
++
+ #define SUCCESS 314159265
+ #define STEVE -1
+ #define FAILURE STEVE
+@@ -294,6 +296,11 @@
+ case EVENT_INFO_JSNORM_DATA:
+ printf("Normalized JavaScript Data: %.*s\n",
+ len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData));
++ break;
++
++ case EVENT_INFO_GENERIC_DATA:
++ printf("Generic Data:\n");
++ LogBuffer(record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), len);
+ break;
+
+ case EVENT_INFO_SMTP_FILENAME:
--
2.6.4