Fix sig grouping bug when certain sigs are mixed. Add tests.

pull/278/head
Victor Julien 13 years ago
parent afb2d4eddf
commit d0c1410cf5

@ -275,11 +275,10 @@ int DetectAddressCutIPv4(DetectEngineCtx *de_ctx, DetectAddress *a,
b->ip2.addr_data32[0] = htonl(a_ip2);
if (de_ctx != NULL) {
/* 'a' overlaps 'b' so 'b' needs the 'a' sigs */
SigGroupHeadCopySigs(de_ctx, a->sh, &tmp->sh);
SigGroupHeadCopySigs(de_ctx, b->sh, &tmp->sh);
SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh);
SigGroupHeadClearSigs(a->sh);
SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh);
SigGroupHeadCopySigs(de_ctx, tmp->sh, &b->sh);
SigGroupHeadCopySigs(de_ctx, tmp->sh, &a->sh);
SigGroupHeadClearSigs(tmp->sh);
for (port = a->port; port != NULL; port = port->next)
@ -1596,7 +1595,6 @@ static int DetectAddressIPv4Join10(void)
void DetectAddressIPv4Tests(void)
{
#ifdef UNITTESTS
UtRegisterTest("DetectAddressIPv4TestAddressCmp01",
DetectAddressIPv4TestAddressCmp01, 1);
@ -1613,6 +1611,4 @@ void DetectAddressIPv4Tests(void)
UtRegisterTest("DetectAddressIPv4CutNot09", DetectAddressIPv4CutNot09, 1);
UtRegisterTest("DetectAddressIPv4Join10", DetectAddressIPv4Join10, 1);
#endif
return;
}

@ -512,11 +512,10 @@ int DetectAddressCutIPv6(DetectEngineCtx *de_ctx, DetectAddress *a,
AddressCutIPv6Copy(a_ip1, b->ip.addr_data32);
AddressCutIPv6Copy(a_ip2, b->ip2.addr_data32);
/* 'a' overlaps 'b' so 'b' needs the 'a' sigs */
SigGroupHeadCopySigs(de_ctx, a->sh, &tmp->sh);
SigGroupHeadCopySigs(de_ctx, b->sh, &tmp->sh);
SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh);
SigGroupHeadClearSigs(a->sh);
SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh);
SigGroupHeadCopySigs(de_ctx, tmp->sh, &b->sh);
SigGroupHeadCopySigs(de_ctx, tmp->sh, &a->sh);
SigGroupHeadClearSigs(tmp->sh);
for (port = a->port; port != NULL; port = port->next)

@ -1657,9 +1657,9 @@ void DetectAddressPrint(DetectAddress *gr)
struct in6_addr in6;
char ip[66], mask[66];
memcpy(&in6, &gr->ip, sizeof(in6));
memcpy(&in6, &gr->ip.addr_data32, sizeof(in6));
PrintInet(AF_INET6, &in6, ip, sizeof(ip));
memcpy(&in6, &gr->ip2, sizeof(in6));
memcpy(&in6, &gr->ip2.addr_data32, sizeof(in6));
PrintInet(AF_INET6, &in6, mask, sizeof(mask));
SCLogDebug("%s/%s", ip, mask);
@ -2251,6 +2251,53 @@ int AddressTestParse35(void)
return 0;
}
int AddressTestParse36(void)
{
int result = 1;
DetectAddress *dd = DetectAddressParseSingle("ffff::/16");
if (dd) {
if (dd->ip.addr_data32[0] != 0x0000FFFF || dd->ip.addr_data32[1] != 0x00000000 ||
dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF ||
dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
DetectAddressPrint(dd);
result = 0;
}
DetectAddressPrint(dd);
DetectAddressFree(dd);
return result;
}
return 0;
}
int AddressTestParse37(void)
{
int result = 1;
DetectAddress *dd = DetectAddressParseSingle("::/0");
if (dd) {
if (dd->ip.addr_data32[0] != 0x00000000 || dd->ip.addr_data32[1] != 0x00000000 ||
dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 ||
dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF ||
dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) {
DetectAddressPrint(dd);
result = 0;
}
DetectAddressPrint(dd);
DetectAddressFree(dd);
return result;
}
return 0;
}
int AddressTestMatch01(void)
{
DetectAddress *dd = NULL;
@ -4359,6 +4406,316 @@ int AddressConfVarsTest05(void)
return result;
}
#include "detect-engine.h"
/**
* \test Test sig distribution over address groups
*/
static int AddressTestFunctions01(void) {
DetectAddress *a1 = NULL;
DetectAddress *a2 = NULL;
DetectAddressHead *h = NULL;
int result = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
Signature s[2];
memset(s,0x00,sizeof(s));
s[0].num = 0;
s[1].num = 1;
a1 = DetectAddressParseSingle("255.0.0.0/8");
if (a1 == NULL) {
printf("a1 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]);
a2 = DetectAddressParseSingle("0.0.0.0/0");
if (a2 == NULL) {
printf("a2 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]);
SCLogDebug("a1");
DetectAddressPrint(a1);
SCLogDebug("a2");
DetectAddressPrint(a2);
h = DetectAddressHeadInit();
if (h == NULL)
goto end;
DetectAddressInsert(de_ctx, h, a1);
DetectAddressInsert(de_ctx, h, a2);
if (h == NULL)
goto end;
DetectAddress *x = h->ipv4_head;
for ( ; x != NULL; x = x->next) {
SCLogDebug("x %p next %p", x, x->next);
DetectAddressPrint(x);
//SigGroupHeadPrintSigs(de_ctx, x->sh);
}
DetectAddress *one = h->ipv4_head;
DetectAddress *two = one->next;
int sig = 0;
if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'two', but it shouldn't: ", sig);
goto end;
}
result = 1;
end:
if (h != NULL)
DetectAddressHeadFree(h);
return result;
}
/**
* \test Test sig distribution over address groups
*/
static int AddressTestFunctions02(void) {
DetectAddress *a1 = NULL;
DetectAddress *a2 = NULL;
DetectAddressHead *h = NULL;
int result = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
Signature s[2];
memset(s,0x00,sizeof(s));
s[0].num = 0;
s[1].num = 1;
a1 = DetectAddressParseSingle("255.0.0.0/8");
if (a1 == NULL) {
printf("a1 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]);
a2 = DetectAddressParseSingle("0.0.0.0/0");
if (a2 == NULL) {
printf("a2 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]);
SCLogDebug("a1");
DetectAddressPrint(a1);
SCLogDebug("a2");
DetectAddressPrint(a2);
h = DetectAddressHeadInit();
if (h == NULL)
goto end;
DetectAddressInsert(de_ctx, h, a2);
DetectAddressInsert(de_ctx, h, a1);
BUG_ON(h == NULL);
SCLogDebug("dp3");
DetectAddress *x = h->ipv4_head;
for ( ; x != NULL; x = x->next) {
DetectAddressPrint(x);
//SigGroupHeadPrintSigs(de_ctx, x->sh);
}
DetectAddress *one = h->ipv4_head;
DetectAddress *two = one->next;
int sig = 0;
if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'two', but it shouldn't: ", sig);
goto end;
}
result = 1;
end:
if (h != NULL)
DetectAddressHeadFree(h);
return result;
}
/**
* \test Test sig distribution over address groups
*/
static int AddressTestFunctions03(void) {
DetectAddress *a1 = NULL;
DetectAddress *a2 = NULL;
DetectAddressHead *h = NULL;
int result = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
Signature s[2];
memset(s,0x00,sizeof(s));
s[0].num = 0;
s[1].num = 1;
a1 = DetectAddressParseSingle("ffff::/16");
if (a1 == NULL) {
printf("a1 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]);
a2 = DetectAddressParseSingle("::/0");
if (a2 == NULL) {
printf("a2 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]);
SCLogDebug("a1");
DetectAddressPrint(a1);
SCLogDebug("a2");
DetectAddressPrint(a2);
h = DetectAddressHeadInit();
if (h == NULL)
goto end;
DetectAddressInsert(de_ctx, h, a1);
DetectAddressInsert(de_ctx, h, a2);
if (h == NULL)
goto end;
DetectAddress *x = h->ipv6_head;
for ( ; x != NULL; x = x->next) {
SCLogDebug("x %p next %p", x, x->next);
DetectAddressPrint(x);
//SigGroupHeadPrintSigs(de_ctx, x->sh);
}
DetectAddress *one = h->ipv6_head;
DetectAddress *two = one->next;
int sig = 0;
if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'two', but it shouldn't: ", sig);
goto end;
}
result = 1;
end:
if (h != NULL)
DetectAddressHeadFree(h);
return result;
}
/**
* \test Test sig distribution over address groups
*/
static int AddressTestFunctions04(void) {
DetectAddress *a1 = NULL;
DetectAddress *a2 = NULL;
DetectAddressHead *h = NULL;
int result = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
Signature s[2];
memset(s,0x00,sizeof(s));
s[0].num = 0;
s[1].num = 1;
a1 = DetectAddressParseSingle("ffff::/16");
if (a1 == NULL) {
printf("a1 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]);
a2 = DetectAddressParseSingle("::/0");
if (a2 == NULL) {
printf("a2 == NULL: ");
goto end;
}
SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]);
SCLogDebug("a1");
DetectAddressPrint(a1);
SCLogDebug("a2");
DetectAddressPrint(a2);
h = DetectAddressHeadInit();
if (h == NULL)
goto end;
DetectAddressInsert(de_ctx, h, a2);
DetectAddressInsert(de_ctx, h, a1);
BUG_ON(h == NULL);
SCLogDebug("dp3");
DetectAddress *x = h->ipv6_head;
for ( ; x != NULL; x = x->next) {
DetectAddressPrint(x);
//SigGroupHeadPrintSigs(de_ctx, x->sh);
}
DetectAddress *one = h->ipv6_head;
DetectAddress *two = one->next;
int sig = 0;
if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'two', but it shouldn't: ", sig);
goto end;
}
result = 1;
end:
if (h != NULL)
DetectAddressHeadFree(h);
return result;
}
#endif /* UNITTESTS */
void DetectAddressTests(void)
@ -4402,6 +4759,8 @@ void DetectAddressTests(void)
UtRegisterTest("AddressTestParse33", AddressTestParse33, 1);
UtRegisterTest("AddressTestParse34", AddressTestParse34, 1);
UtRegisterTest("AddressTestParse35", AddressTestParse35, 1);
UtRegisterTest("AddressTestParse36", AddressTestParse36, 1);
UtRegisterTest("AddressTestParse37", AddressTestParse37, 1);
UtRegisterTest("AddressTestMatch01", AddressTestMatch01, 1);
UtRegisterTest("AddressTestMatch02", AddressTestMatch02, 1);
@ -4538,5 +4897,9 @@ void DetectAddressTests(void)
UtRegisterTest("AddressConfVarsTest04 ", AddressConfVarsTest04, 1);
UtRegisterTest("AddressConfVarsTest05 ", AddressConfVarsTest05, 1);
UtRegisterTest("AddressTestFunctions01", AddressTestFunctions01, 1);
UtRegisterTest("AddressTestFunctions02", AddressTestFunctions02, 1);
UtRegisterTest("AddressTestFunctions03", AddressTestFunctions03, 1);
UtRegisterTest("AddressTestFunctions04", AddressTestFunctions04, 1);
#endif /* UNITTESTS */
}

@ -494,10 +494,20 @@ static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a,
b->port = a_port1;
b->port2 = a_port2;
/** 'a' overlaps 'b' so 'b' needs the 'a' sigs */
/* [bbb[baba]] will be transformed into
* [aaa][bbb]
* steps: copy b sigs to tmp
* a overlaps b, so copy a to b
* clear a
* copy tmp to a */
SigGroupHeadCopySigs(de_ctx,b->sh,&tmp->sh); /* store old a list */
tmp->cnt = b->cnt;
SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh);
b->cnt += a->cnt;
SigGroupHeadClearSigs(a->sh); /* clean a list */
SigGroupHeadCopySigs(de_ctx,tmp->sh,&a->sh);/* merge old a with b */
a->cnt = tmp->cnt;
SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
} else {
SCLogDebug("3");
a->port = b_port1;
@ -579,6 +589,7 @@ static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a,
} else if (a_port2 == b_port2) {
SCLogDebug("2");
a->port = a_port1;
a->port2 = b_port1 - 1;
@ -2263,6 +2274,160 @@ end:
return result;
}
/**
* \test Test general functions
*/
static int PortTestFunctions05(void) {
DetectPort *dp1 = NULL;
DetectPort *dp2 = NULL;
DetectPort *dp3 = NULL;
int result = 0;
int r = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
Signature s[2];
memset(s,0x00,sizeof(s));
s[0].num = 0;
s[1].num = 1;
r = DetectPortParse(&dp1, "1024:65535");
if (r != 0) {
printf("r != 0 but %d: ", r);
goto end;
}
SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]);
r = DetectPortParse(&dp2, "any");
if (r != 0) {
printf("r != 0 but %d: ", r);
goto end;
}
SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]);
SCLogDebug("dp1");
DetectPortPrint(dp1);
SCLogDebug("dp2");
DetectPortPrint(dp2);
DetectPortInsert(de_ctx, &dp3, dp1);
DetectPortInsert(de_ctx, &dp3, dp2);
if (dp3 == NULL)
goto end;
SCLogDebug("dp3");
DetectPort *x = dp3;
for ( ; x != NULL; x = x->next) {
DetectPortPrint(x);
//SigGroupHeadPrintSigs(de_ctx, x->sh);
}
DetectPort *one = dp3;
DetectPort *two = dp3->next;
int sig = 0;
if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'two', but it shouldn't: ", sig);
goto end;
}
result = 1;
end:
if (dp1 != NULL)
DetectPortFree(dp1);
if (dp2 != NULL)
DetectPortFree(dp2);
return result;
}
/**
* \test Test general functions
*/
static int PortTestFunctions06(void) {
DetectPort *dp1 = NULL;
DetectPort *dp2 = NULL;
DetectPort *dp3 = NULL;
int result = 0;
int r = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
Signature s[2];
memset(s,0x00,sizeof(s));
s[0].num = 0;
s[1].num = 1;
r = DetectPortParse(&dp1, "1024:65535");
if (r != 0) {
printf("r != 0 but %d: ", r);
goto end;
}
SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]);
r = DetectPortParse(&dp2, "any");
if (r != 0) {
printf("r != 0 but %d: ", r);
goto end;
}
SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]);
SCLogDebug("dp1");
DetectPortPrint(dp1);
SCLogDebug("dp2");
DetectPortPrint(dp2);
DetectPortInsert(de_ctx, &dp3, dp2);
DetectPortInsert(de_ctx, &dp3, dp1);
if (dp3 == NULL)
goto end;
SCLogDebug("dp3");
DetectPort *x = dp3;
for ( ; x != NULL; x = x->next) {
DetectPortPrint(x);
//SigGroupHeadPrintSigs(de_ctx, x->sh);
}
DetectPort *one = dp3;
DetectPort *two = dp3->next;
int sig = 0;
if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'one', but it shouldn't: ", sig);
goto end;
}
sig = 1;
if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) {
printf("sig %d part of 'two', but it shouldn't: ", sig);
goto end;
}
result = 1;
end:
if (dp1 != NULL)
DetectPortFree(dp1);
if (dp2 != NULL)
DetectPortFree(dp2);
return result;
}
/**
* \test Test packet Matches
* \param raw_eth_pkt pointer to the ethernet packet
@ -2581,6 +2746,8 @@ void DetectPortTests(void) {
UtRegisterTest("PortTestFunctions02", PortTestFunctions02, 1);
UtRegisterTest("PortTestFunctions03", PortTestFunctions03, 1);
UtRegisterTest("PortTestFunctions04", PortTestFunctions04, 1);
UtRegisterTest("PortTestFunctions05", PortTestFunctions05, 1);
UtRegisterTest("PortTestFunctions06", PortTestFunctions06, 1);
UtRegisterTest("PortTestMatchReal01", PortTestMatchReal01, 1);
UtRegisterTest("PortTestMatchReal02", PortTestMatchReal02, 1);
UtRegisterTest("PortTestMatchReal03", PortTestMatchReal03, 1);

@ -2309,13 +2309,65 @@ end:
UTHFreePackets(&p, 1);
return result;
}
/**
* \test sig grouping bug.
*/
static int SigGroupHeadTest11(void)
{
int result = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
Signature *s = NULL;
Packet *p = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
ThreadVars th_v;
memset(&th_v, 0, sizeof(ThreadVars));
p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "192.168.1.1", "1.2.3.4", 60000, 80);
if (de_ctx == NULL || p == NULL)
return 0;
s = DetectEngineAppendSig(de_ctx, "alert tcp any 1024: -> any 1024: (content:\"abc\"; sid:1;)");
if (s == NULL) {
goto end;
}
s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"def\"; http_client_body; sid:2;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
AddressDebugPrint(&p->dst);
SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p);
if (sgh == NULL) {
goto end;
}
/* check if hcbd flag is set in sgh */
if (!(sgh->flags & SIG_GROUP_HEAD_MPM_HCBD)) {
printf("sgh has not SIG_GROUP_HEAD_MPM_HCBD flag set: ");
goto end;
}
/* check if sig 2 is part of the sgh */
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
UTHFreePackets(&p, 1);
return result;
}
#endif
void SigGroupHeadRegisterTests(void)
{
#ifdef UNITTESTS
UtRegisterTest("SigGroupHeadTest01", SigGroupHeadTest01, 1);
UtRegisterTest("SigGroupHeadTest02", SigGroupHeadTest02, 1);
UtRegisterTest("SigGroupHeadTest03", SigGroupHeadTest03, 1);
@ -2326,7 +2378,6 @@ void SigGroupHeadRegisterTests(void)
UtRegisterTest("SigGroupHeadTest08", SigGroupHeadTest08, 1);
UtRegisterTest("SigGroupHeadTest09", SigGroupHeadTest09, 1);
UtRegisterTest("SigGroupHeadTest10", SigGroupHeadTest10, 1);
UtRegisterTest("SigGroupHeadTest11", SigGroupHeadTest11, 1);
#endif
}

Loading…
Cancel
Save