4040#include "action-globals.h"
4141#include "flow-util.h"
4242#include "util-validate.h"
43+ #include "rust.h"
4344
4445#define DETECT_FLOWVAR_NOT_USED 1
4546#define DETECT_FLOWVAR_TYPE_READ 2
@@ -546,6 +547,13 @@ static int SCSigLessThan(SCSigSignatureWrapper *sw1,
546547
547548 funcs = funcs -> next ;
548549 }
550+
551+ // Special handling for flowbits, do not touch the order if the comparison fn
552+ // calculates two signatures to be equal
553+ if ((sw1 -> user [DETECT_SIGORDER_FLOWBITS ] > DETECT_FLOWBITS_NOT_USED ) &&
554+ (sw1 -> user [DETECT_SIGORDER_FLOWBITS ] == sw2 -> user [DETECT_SIGORDER_FLOWBITS ]))
555+ return 0 ;
556+
549557 // They are equal, so use sid as the final decider.
550558 return sw1 -> sig -> id < sw2 -> sig -> id ;
551559}
@@ -621,6 +629,113 @@ static SCSigSignatureWrapper *SCSigOrder(SCSigSignatureWrapper *sw,
621629 return result ;
622630}
623631
632+ static SCSigSignatureWrapper * SCSigResolveFlowbitDependencies (SCSigSignatureWrapper * arg_sw )
633+ {
634+ uint32_t sig_cnt = 0 ;
635+ uint32_t * sorted_siids = NULL ;
636+ SCSigSignatureWrapper * sw = arg_sw ;
637+
638+ void * graph = SCCreateDirectedGraph ();
639+
640+ while (sw != NULL ) {
641+ Signature * s = sw -> sig ;
642+ int64_t sidx = SCCreateNodeEdgeDirectedGraph (graph , s -> iid , false /* Signature type node */ ,
643+ false /* does not matter */ , UINT32_MAX /* no signature index in graph yet */ );
644+ if (sidx < 0 ) {
645+ goto error ;
646+ }
647+ DEBUG_VALIDATE_BUG_ON (sidx > UINT32_MAX );
648+ SigMatch * sm = s -> init_data -> smlists [DETECT_SM_LIST_MATCH ];
649+ DetectFlowbitsData * fbd = NULL ;
650+ int64_t nidx = 0 ;
651+
652+ while (sm != NULL ) {
653+ if (sm -> type != DETECT_FLOWBITS ) {
654+ sm = sm -> next ;
655+ continue ;
656+ }
657+ fbd = (DetectFlowbitsData * )sm -> ctx ;
658+ nidx = SCCreateNodeEdgeDirectedGraph (graph , fbd -> idx , true /* Flowbit type node */ ,
659+ false /* READ cmd */ , (uint32_t )sidx );
660+ if (nidx < 0 ) {
661+ goto error ;
662+ }
663+ sm = sm -> next ;
664+ }
665+
666+ sm = s -> init_data -> smlists [DETECT_SM_LIST_POSTMATCH ];
667+
668+ while (sm != NULL ) {
669+ if (sm -> type != DETECT_FLOWBITS ) {
670+ sm = sm -> next ;
671+ continue ;
672+ }
673+ fbd = (DetectFlowbitsData * )sm -> ctx ;
674+ nidx = SCCreateNodeEdgeDirectedGraph (graph , fbd -> idx , true /* Flowbit type node */ ,
675+ true /* WRITE cmd */ , (uint32_t )sidx );
676+ if (nidx < 0 ) {
677+ goto error ;
678+ }
679+ sm = sm -> next ;
680+ }
681+
682+ sw = sw -> next ;
683+ sig_cnt ++ ;
684+ }
685+
686+ DEBUG_VALIDATE_BUG_ON (sig_cnt == 0 );
687+
688+ sorted_siids = SCCalloc (sig_cnt , sizeof (uint32_t ));
689+ if (sorted_siids == NULL ) {
690+ goto error ;
691+ }
692+ if (SCResolveFlowbitDependencies (graph , sorted_siids , sig_cnt ) < 0 ) {
693+ goto error ;
694+ }
695+
696+ SCSigSignatureWrapper * fin = NULL ;
697+ SCSigSignatureWrapper * tmp = NULL ;
698+ SCSigSignatureWrapper * prev = NULL ;
699+
700+ for (uint32_t i = 0 ; i < sig_cnt ; i ++ ) {
701+ sw = arg_sw ;
702+ while (sw != NULL ) {
703+ if (sorted_siids [i ] == sw -> sig -> iid ) {
704+ if (tmp ) {
705+ prev -> next = sw -> next ;
706+ sw -> next = NULL ;
707+ tmp -> next = sw ;
708+ } else {
709+ tmp = sw ;
710+ fin = tmp ;
711+ }
712+ }
713+ prev = sw ;
714+ sw = sw -> next ;
715+ }
716+ }
717+
718+ #ifdef DEBUG
719+ tmp = fin ;
720+ while (tmp != NULL ) {
721+ SCLogDebug ("sid: %d, iid: %d" , tmp -> sig -> id , tmp -> sig -> iid );
722+ tmp = tmp -> next ;
723+ }
724+ #endif
725+
726+ SCFree (sorted_siids ); /* No longer needed */
727+ SCFreeDirectedGraph (graph );
728+ return fin ;
729+
730+ error :
731+ SCLogError ("Error resolving flowbit dependencies; rolling back to original order" );
732+ if (sorted_siids != NULL ) {
733+ SCFree (sorted_siids );
734+ }
735+ SCFreeDirectedGraph (graph );
736+ return arg_sw ;
737+ }
738+
624739/**
625740 * \brief Orders an incoming Signature based on its action
626741 *
@@ -631,6 +746,7 @@ static SCSigSignatureWrapper *SCSigOrder(SCSigSignatureWrapper *sw,
631746static int SCSigOrderByActionCompare (SCSigSignatureWrapper * sw1 ,
632747 SCSigSignatureWrapper * sw2 )
633748{
749+ SCLogDebug ("Comparing by Action sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
634750 return ActionOrderVal (sw2 -> sig -> action ) - ActionOrderVal (sw1 -> sig -> action );
635751}
636752
@@ -644,6 +760,7 @@ static int SCSigOrderByActionCompare(SCSigSignatureWrapper *sw1,
644760static int SCSigOrderByFlowbitsCompare (SCSigSignatureWrapper * sw1 ,
645761 SCSigSignatureWrapper * sw2 )
646762{
763+ SCLogDebug ("Comparing by Flowbits sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
647764 return sw1 -> user [DETECT_SIGORDER_FLOWBITS ] - sw2 -> user [DETECT_SIGORDER_FLOWBITS ];
648765}
649766
@@ -657,6 +774,7 @@ static int SCSigOrderByFlowbitsCompare(SCSigSignatureWrapper *sw1,
657774static int SCSigOrderByFlowvarCompare (SCSigSignatureWrapper * sw1 ,
658775 SCSigSignatureWrapper * sw2 )
659776{
777+ SCLogDebug ("Comparing by Flowvar sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
660778 return sw1 -> user [DETECT_SIGORDER_FLOWVAR ] - sw2 -> user [DETECT_SIGORDER_FLOWVAR ];
661779}
662780
@@ -670,12 +788,14 @@ static int SCSigOrderByFlowvarCompare(SCSigSignatureWrapper *sw1,
670788static int SCSigOrderByPktvarCompare (SCSigSignatureWrapper * sw1 ,
671789 SCSigSignatureWrapper * sw2 )
672790{
791+ SCLogDebug ("Comparing by Pktvar sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
673792 return sw1 -> user [DETECT_SIGORDER_PKTVAR ] - sw2 -> user [DETECT_SIGORDER_PKTVAR ];
674793}
675794
676795static int SCSigOrderByFlowintCompare (SCSigSignatureWrapper * sw1 ,
677796 SCSigSignatureWrapper * sw2 )
678797{
798+ SCLogDebug ("Comparing by Flowint sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
679799 return sw1 -> user [DETECT_SIGORDER_FLOWINT ] - sw2 -> user [DETECT_SIGORDER_FLOWINT ];
680800}
681801
@@ -689,6 +809,7 @@ static int SCSigOrderByFlowintCompare(SCSigSignatureWrapper *sw1,
689809static int SCSigOrderByHostbitsCompare (SCSigSignatureWrapper * sw1 ,
690810 SCSigSignatureWrapper * sw2 )
691811{
812+ SCLogDebug ("Comparing by Hostbits sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
692813 return sw1 -> user [DETECT_SIGORDER_HOSTBITS ] - sw2 -> user [DETECT_SIGORDER_HOSTBITS ];
693814}
694815
@@ -702,6 +823,7 @@ static int SCSigOrderByHostbitsCompare(SCSigSignatureWrapper *sw1,
702823static int SCSigOrderByIPPairbitsCompare (SCSigSignatureWrapper * sw1 ,
703824 SCSigSignatureWrapper * sw2 )
704825{
826+ SCLogDebug ("Comparing by IPPair sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
705827 return sw1 -> user [DETECT_SIGORDER_IPPAIRBITS ] - sw2 -> user [DETECT_SIGORDER_IPPAIRBITS ];
706828}
707829
@@ -715,6 +837,7 @@ static int SCSigOrderByIPPairbitsCompare(SCSigSignatureWrapper *sw1,
715837static int SCSigOrderByPriorityCompare (SCSigSignatureWrapper * sw1 ,
716838 SCSigSignatureWrapper * sw2 )
717839{
840+ SCLogDebug ("Comparing by Priority sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
718841 if (sw1 -> sig -> prio > sw2 -> sig -> prio ) {
719842 return -1 ;
720843 } else if (sw1 -> sig -> prio < sw2 -> sig -> prio ) {
@@ -725,6 +848,7 @@ static int SCSigOrderByPriorityCompare(SCSigSignatureWrapper *sw1,
725848
726849static int SCSigOrderByIId (SCSigSignatureWrapper * sw1 , SCSigSignatureWrapper * sw2 )
727850{
851+ SCLogDebug ("Comparing by IID sid1: %d and sid2: %d" , sw1 -> sig -> id , sw2 -> sig -> id );
728852 if (sw1 -> sig -> iid > sw2 -> sig -> iid ) {
729853 return -1 ;
730854 } else if (sw1 -> sig -> iid < sw2 -> sig -> iid ) {
@@ -810,12 +934,29 @@ void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
810934
811935 SCLogDebug ("ordering signatures in memory" );
812936 SCSigSignatureWrapper * sigw = NULL ;
813- SCSigSignatureWrapper * td_sigw_list = NULL ; /* unified td list */
937+ SCSigSignatureWrapper * td_sigw_list_start = NULL ; /* unified td list */
938+ SCSigSignatureWrapper * td_sigw_list_end = NULL ; /* unified td list */
939+
940+ SCSigSignatureWrapper * s_fb_sigw_list_start = NULL ; /* SET flowbits */
941+ SCSigSignatureWrapper * r_fb_sigw_list_start = NULL ; /* READ flowbits */
942+ SCSigSignatureWrapper * sr_fb_sigw_list_start = NULL ; /* SET_READ flowbits */
943+
944+ SCSigSignatureWrapper * s_fb_sigw_list_end = NULL ; /* SET flowbits */
945+ // SCSigSignatureWrapper *r_fb_sigw_list_end = NULL; /* READ flowbits */
946+ SCSigSignatureWrapper * sr_fb_sigw_list_end = NULL ; /* SET_READ flowbits */
814947
815948 SCSigSignatureWrapper * fw_pf_sigw_list = NULL ; /* hook: packet_filter */
816949 SCSigSignatureWrapper * fw_af_sigw_list = NULL ; /* hook: app_filter */
817950
818951 Signature * sig = de_ctx -> sig_list ;
952+
953+ #ifdef DEBUG
954+ SCLogDebug (">>>>>>>>>>>>>>>BEGIN" );
955+ for (Signature * s = de_ctx -> sig_list ; s != NULL ; s = s -> next ) {
956+ SCLogDebug ("sid: %d; iid: %d" , s -> id , s -> iid );
957+ }
958+ SCLogDebug (">>>>>>>>>>>>>>>END" );
959+ #endif
819960 while (sig != NULL ) {
820961 sigw = SCSigAllocSignatureWrapper (sig );
821962 /* Push signature wrapper onto a list, order doesn't matter here. */
@@ -829,8 +970,25 @@ void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
829970 fw_af_sigw_list = sigw ;
830971 }
831972 } else {
832- sigw -> next = td_sigw_list ;
833- td_sigw_list = sigw ;
973+ if (sigw -> user [DETECT_SIGORDER_FLOWBITS ] != DETECT_FLOWBITS_NOT_USED ) {
974+ if (sigw -> user [DETECT_SIGORDER_FLOWBITS ] == DETECT_FLOWBITS_TYPE_SET_READ ) {
975+ sigw -> next = sr_fb_sigw_list_start ;
976+ sr_fb_sigw_list_start = sigw ;
977+ } else if (sigw -> user [DETECT_SIGORDER_FLOWBITS ] == DETECT_FLOWBITS_TYPE_READ ) {
978+ sigw -> next = r_fb_sigw_list_start ;
979+ r_fb_sigw_list_start = sigw ;
980+ } else if (sigw -> user [DETECT_SIGORDER_FLOWBITS ] == DETECT_FLOWBITS_TYPE_SET ) {
981+ sigw -> next = s_fb_sigw_list_start ;
982+ if (!s_fb_sigw_list_end )
983+ s_fb_sigw_list_end = sigw ;
984+ s_fb_sigw_list_start = sigw ;
985+ }
986+ } else {
987+ sigw -> next = td_sigw_list_start ;
988+ if (!td_sigw_list_end )
989+ td_sigw_list_end = sigw ;
990+ td_sigw_list_start = sigw ;
991+ }
834992 }
835993 sig = sig -> next ;
836994 }
@@ -846,10 +1004,64 @@ void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
8461004 SCSigOrderFunc OrderFn = { .SWCompare = SCSigOrderByAppFirewall , .next = NULL };
8471005 fw_af_sigw_list = SCSigOrder (fw_af_sigw_list , & OrderFn );
8481006 }
849- if (td_sigw_list ) {
1007+ if (sr_fb_sigw_list_start ) {
1008+ /* Resolve any complex dependencies, if possible, or error out early on */
1009+ sr_fb_sigw_list_start = SCSigResolveFlowbitDependencies (sr_fb_sigw_list_start );
1010+ SCSigSignatureWrapper * tmp = sr_fb_sigw_list_start ;
1011+ while (tmp != NULL ) {
1012+ sr_fb_sigw_list_end = tmp ;
1013+ tmp = tmp -> next ;
1014+ }
1015+ }
1016+ /* Merge the flowbit lists into the generic thread detection list */
1017+ SCSigSignatureWrapper * tmp = NULL ;
1018+ if (s_fb_sigw_list_end ) {
1019+ s_fb_sigw_list_end -> next = sr_fb_sigw_list_start ;
1020+ tmp = s_fb_sigw_list_start ;
1021+ }
1022+ if (sr_fb_sigw_list_end ) {
1023+ sr_fb_sigw_list_end -> next = r_fb_sigw_list_start ;
1024+ if (!tmp )
1025+ tmp = sr_fb_sigw_list_start ;
1026+ }
1027+ if (r_fb_sigw_list_start ) {
1028+ if (!sr_fb_sigw_list_start && s_fb_sigw_list_end )
1029+ s_fb_sigw_list_end -> next = r_fb_sigw_list_start ;
1030+ if (!tmp )
1031+ tmp = r_fb_sigw_list_start ;
1032+ }
1033+
1034+ #ifdef DEBUG
1035+ SCSigSignatureWrapper * tmp2 = tmp ;
1036+ SCLogDebug (">>>>>>>>>>>>>>>BEGIN" );
1037+ while (tmp2 != NULL ) {
1038+ SCLogDebug ("tmp sid: %d, iid: %d" , tmp2 -> sig -> id , tmp2 -> sig -> iid );
1039+ tmp2 = tmp2 -> next ;
1040+ }
1041+ SCLogDebug (">>>>>>>>>>>>>>>END" );
1042+ #endif
1043+
1044+ if (td_sigw_list_end ) {
1045+ td_sigw_list_end -> next = tmp ;
1046+ /* Sort the list */
1047+ td_sigw_list_start = SCSigOrder (td_sigw_list_start , de_ctx -> sc_sig_order_funcs );
1048+ } else if (tmp ) {
1049+ td_sigw_list_start = tmp ;
8501050 /* Sort the list */
851- td_sigw_list = SCSigOrder (td_sigw_list , de_ctx -> sc_sig_order_funcs );
1051+ td_sigw_list_start = SCSigOrder (td_sigw_list_start , de_ctx -> sc_sig_order_funcs );
8521052 }
1053+
1054+ #ifdef DEBUG
1055+ SCLogDebug ("POST MERGE SORT" );
1056+ tmp2 = td_sigw_list_start ;
1057+ SCLogDebug (">>>>>>>>>>>>>>>BEGIN" );
1058+ while (tmp2 != NULL ) {
1059+ SCLogDebug ("tmp sid: %d, iid: %d" , tmp2 -> sig -> id , tmp2 -> sig -> iid );
1060+ tmp2 = tmp2 -> next ;
1061+ }
1062+ SCLogDebug (">>>>>>>>>>>>>>>END" );
1063+ #endif
1064+
8531065 /* Recreate the sig list in order */
8541066 de_ctx -> sig_list = NULL ;
8551067
@@ -888,7 +1100,7 @@ void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
8881100 SCFree (sigw_to_free );
8891101 }
8901102 /* threat detect list for hook app_td */
891- for (sigw = td_sigw_list ; sigw != NULL ;) {
1103+ for (sigw = td_sigw_list_start ; sigw != NULL ;) {
8921104 sigw -> sig -> next = NULL ;
8931105 if (de_ctx -> sig_list == NULL ) {
8941106 /* First entry on the list */
0 commit comments