Set decoder event on fragment overlaps.

remotes/origin/master-1.1.x
Jason Ish 15 years ago committed by Victor Julien
parent 7f5e120d60
commit de1c40c44f

@ -70,5 +70,6 @@ alert pkthdr any any -> any any (msg:"SURICATA VLAN header too small "; decode-e
alert pkthdr any any -> any any (msg:"SURICATA VLAN unknown type"; decode-event:vlan.unknown_type; sid:22000066; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA VLAN unknown type"; decode-event:vlan.unknown_type; sid:22000066; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA IP raw invalid IP version "; decode-event:ipraw.invalid_ip_version; sid:22000067; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA IP raw invalid IP version "; decode-event:ipraw.invalid_ip_version; sid:22000067; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA FRAG Packet size too large"; decode-event:frag.too_large; sid:22000067; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA FRAG Packet size too large"; decode-event:frag.too_large; sid:22000067; rev:1;)
alert pkthdr any any -> any any (msg:"SURICATA FRAG Fragmentation overlap"; decode-event:frag.overlap; sid:22000068; rev:1;)

@ -182,6 +182,7 @@ enum {
/* Fragmentation reasembly events. */ /* Fragmentation reasembly events. */
FRAG_PKT_TOO_LARGE, FRAG_PKT_TOO_LARGE,
FRAG_OVERLAP,
/* should always be last! */ /* should always be last! */
DECODE_EVENT_MAX, DECODE_EVENT_MAX,

@ -816,6 +816,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
tracker->timeout.tv_sec += dc->timeout; tracker->timeout.tv_sec += dc->timeout;
Frag *prev = NULL, *next; Frag *prev = NULL, *next;
int overlap = 0;
if (!TAILQ_EMPTY(&tracker->frags)) { if (!TAILQ_EMPTY(&tracker->frags)) {
TAILQ_FOREACH(prev, &tracker->frags, next) { TAILQ_FOREACH(prev, &tracker->frags, next) {
ltrim = 0; ltrim = 0;
@ -826,13 +827,16 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
if (frag_offset < prev->offset + prev->data_len) { if (frag_offset < prev->offset + prev->data_len) {
if (frag_offset >= prev->offset) { if (frag_offset >= prev->offset) {
ltrim = prev->offset + prev->data_len - frag_offset; ltrim = prev->offset + prev->data_len - frag_offset;
overlap++;
} }
if ((next != NULL) && (frag_end > next->offset)) { if ((next != NULL) && (frag_end > next->offset)) {
next->ltrim = frag_end - next->offset; next->ltrim = frag_end - next->offset;
overlap++;
} }
if ((frag_offset < prev->offset) && if ((frag_offset < prev->offset) &&
(frag_end >= prev->offset + prev->data_len)) { (frag_end >= prev->offset + prev->data_len)) {
prev->skip = 1; prev->skip = 1;
overlap++;
} }
goto insert; goto insert;
} }
@ -841,13 +845,16 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
if (frag_offset < prev->offset + prev->data_len) { if (frag_offset < prev->offset + prev->data_len) {
if (frag_offset > prev->offset) { if (frag_offset > prev->offset) {
ltrim = prev->offset + prev->data_len - frag_offset; ltrim = prev->offset + prev->data_len - frag_offset;
overlap++;
} }
if ((next != NULL) && (frag_end > next->offset)) { if ((next != NULL) && (frag_end > next->offset)) {
next->ltrim = frag_end - next->offset; next->ltrim = frag_end - next->offset;
overlap++;
} }
if ((frag_offset < prev->offset) && if ((frag_offset < prev->offset) &&
(frag_end >= prev->offset + prev->data_len)) { (frag_end >= prev->offset + prev->data_len)) {
prev->skip = 1; prev->skip = 1;
overlap++;
} }
goto insert; goto insert;
} }
@ -856,10 +863,12 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
if (frag_offset < prev->offset + prev->data_len) { if (frag_offset < prev->offset + prev->data_len) {
if (frag_offset >= prev->offset) { if (frag_offset >= prev->offset) {
ltrim = prev->offset + prev->data_len - frag_offset; ltrim = prev->offset + prev->data_len - frag_offset;
overlap++;
} }
if ((frag_offset < prev->offset) && if ((frag_offset < prev->offset) &&
(frag_end > prev->offset + prev->data_len)) { (frag_end > prev->offset + prev->data_len)) {
prev->skip = 1; prev->skip = 1;
overlap++;
} }
goto insert; goto insert;
} }
@ -868,23 +877,28 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
if (frag_offset < prev->offset + prev->data_len) { if (frag_offset < prev->offset + prev->data_len) {
if (frag_offset >= prev->offset) { if (frag_offset >= prev->offset) {
ltrim = prev->offset + prev->data_len - frag_offset; ltrim = prev->offset + prev->data_len - frag_offset;
overlap++;
} }
if ((frag_offset < prev->offset) && if ((frag_offset < prev->offset) &&
(frag_end >= prev->offset + prev->data_len)) { (frag_end >= prev->offset + prev->data_len)) {
prev->skip = 1; prev->skip = 1;
overlap++;
} }
goto insert; goto insert;
} }
break; break;
case DEFRAG_POLICY_FIRST: case DEFRAG_POLICY_FIRST:
if ((frag_offset >= prev->offset) && if ((frag_offset >= prev->offset) &&
(frag_end <= prev->offset + prev->data_len)) (frag_end <= prev->offset + prev->data_len)) {
overlap++;
goto done; goto done;
}
if (frag_offset < prev->offset) { if (frag_offset < prev->offset) {
goto insert; goto insert;
} }
if (frag_offset < prev->offset + prev->data_len) { if (frag_offset < prev->offset + prev->data_len) {
ltrim = prev->offset + prev->data_len - frag_offset; ltrim = prev->offset + prev->data_len - frag_offset;
overlap++;
goto insert; goto insert;
} }
break; break;
@ -892,6 +906,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragContext *dc,
if (frag_offset <= prev->offset) { if (frag_offset <= prev->offset) {
if (frag_end > prev->offset) { if (frag_end > prev->offset) {
prev->ltrim = frag_end - prev->offset; prev->ltrim = frag_end - prev->offset;
overlap++;
} }
goto insert; goto insert;
} }
@ -967,6 +982,9 @@ insert:
} }
done: done:
if (overlap) {
DECODER_SET_EVENT(p, FRAG_OVERLAP);
}
SCMutexUnlock(&tracker->lock); SCMutexUnlock(&tracker->lock);
return r; return r;
} }
@ -1757,13 +1775,29 @@ DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
default_policy = policy; default_policy = policy;
/* Send all but the last. */ /* Send all but the last. */
for (i = 0; i < 16; i++) { for (i = 0; i < 9; i++) {
Packet *tp = Defrag(NULL, NULL, dc, packets[i]); Packet *tp = Defrag(NULL, NULL, dc, packets[i]);
if (tp != NULL) { if (tp != NULL) {
SCFree(tp); SCFree(tp);
goto end; goto end;
} }
if (DECODER_ISSET_EVENT(packets[i], FRAG_OVERLAP)) {
goto end;
}
} }
int overlap = 0;
for (; i < 16; i++) {
Packet *tp = Defrag(NULL, NULL, dc, packets[i]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
if (DECODER_ISSET_EVENT(packets[i], FRAG_OVERLAP)) {
overlap++;
}
}
if (!overlap)
goto end;
/* And now the last one. */ /* And now the last one. */
Packet *reassembled = Defrag(NULL, NULL, dc, packets[16]); Packet *reassembled = Defrag(NULL, NULL, dc, packets[16]);
@ -1880,87 +1914,29 @@ IPV6DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
default_policy = policy; default_policy = policy;
/* Send all but the last. */ /* Send all but the last. */
Packet *tp; for (i = 0; i < 9; i++) {
tp = Defrag(NULL, NULL, dc, packets[0]); Packet *tp = Defrag(NULL, NULL, dc, packets[i]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[1]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[2]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[3]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[4]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[5]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[6]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[7]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[8]);
if (tp != NULL) {
SCFree(tp);
goto end;
}
tp = Defrag(NULL, NULL, dc, packets[9]);
if (tp != NULL) { if (tp != NULL) {
SCFree(tp); SCFree(tp);
goto end; goto end;
} }
tp = Defrag(NULL, NULL, dc, packets[10]); if (DECODER_ISSET_EVENT(packets[i], FRAG_OVERLAP)) {
if (tp != NULL) {
SCFree(tp);
goto end; goto end;
} }
tp = Defrag(NULL, NULL, dc, packets[11]);
if (tp != NULL) {
SCFree(tp);
goto end;
} }
tp = Defrag(NULL, NULL, dc, packets[12]); int overlap = 0;
for (; i < 16; i++) {
Packet *tp = Defrag(NULL, NULL, dc, packets[i]);
if (tp != NULL) { if (tp != NULL) {
SCFree(tp); SCFree(tp);
goto end; goto end;
} }
tp = Defrag(NULL, NULL, dc, packets[13]); if (DECODER_ISSET_EVENT(packets[i], FRAG_OVERLAP)) {
if (tp != NULL) { overlap++;
SCFree(tp);
goto end;
} }
tp = Defrag(NULL, NULL, dc, packets[14]);
if (tp != NULL) {
SCFree(tp);
goto end;
} }
tp = Defrag(NULL, NULL, dc, packets[15]); if (!overlap)
if (tp != NULL) {
SCFree(tp);
goto end; goto end;
}
/* And now the last one. */ /* And now the last one. */
Packet *reassembled = Defrag(NULL, NULL, dc, packets[16]); Packet *reassembled = Defrag(NULL, NULL, dc, packets[16]);

@ -111,6 +111,7 @@ struct DetectDecodeEvents_ {
{ "vlan.header_too_small",VLAN_HEADER_TOO_SMALL, }, { "vlan.header_too_small",VLAN_HEADER_TOO_SMALL, },
{ "vlan.unknown_type",VLAN_UNKNOWN_TYPE, }, { "vlan.unknown_type",VLAN_UNKNOWN_TYPE, },
{ "frag.too_large", FRAG_PKT_TOO_LARGE, }, { "frag.too_large", FRAG_PKT_TOO_LARGE, },
{ "frag.overlap", FRAG_OVERLAP, },
{ NULL, 0 }, { NULL, 0 },
}; };
#endif /* DETECT_EVENTS */ #endif /* DETECT_EVENTS */

Loading…
Cancel
Save