Skip to content
2 changes: 1 addition & 1 deletion rust/src/nfs/nfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub struct NFSTransaction {
pub file_handle: Vec<u8>,

/// Procedure type specific data
/// TODO see if this can be an Option<Box<NFSTransactionTypeData>>. Initial
/// TODO see if this can be an `Option<Box<NFSTransactionTypeData>>`. Initial
/// attempt failed.
pub type_data: Option<NFSTransactionTypeData>,

Expand Down
2 changes: 1 addition & 1 deletion src/detect-engine-alert.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static inline void FlowApplySignatureActions(
* - sig is IP or PD only
* - match is in applayer
* - match is in stream */
if (s->action & (ACTION_DROP | ACTION_PASS)) {
if (pa->action & (ACTION_DROP | ACTION_PASS)) {
if ((pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH)) ||
(s->flags & (SIG_FLAG_IPONLY | SIG_FLAG_LIKE_IPONLY | SIG_FLAG_PDONLY |
SIG_FLAG_APPLAYER))) {
Expand Down
6 changes: 4 additions & 2 deletions src/detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1566,9 +1566,11 @@ static void DetectFlow(ThreadVars *tv,
return;
}

/* if flow is set to drop, we enforce that here */
/* we check the flow drop here, and not the packet drop. This is
* to allow stream engine "invalid" drop packets to still be
* evaluated by the stream event rules. */
if (p->flow->flags & FLOW_ACTION_DROP) {
PacketDrop(p, ACTION_DROP, PKT_DROP_REASON_FLOW_DROP);
DEBUG_VALIDATE_BUG_ON(!(PKT_IS_PSEUDOPKT(p)) && !PACKET_TEST_ACTION(p, ACTION_DROP));
SCReturn;
}

Expand Down
3 changes: 2 additions & 1 deletion src/flow-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ static uint32_t ProcessAsideQueue(FlowManagerTimeoutThread *td, FlowTimeoutCount
while ((f = FlowQueuePrivateGetFromTop(&td->aside_queue)) != NULL) {
/* flow is still locked */

if (f->proto == IPPROTO_TCP && !(f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE) &&
if (f->proto == IPPROTO_TCP &&
!(f->flags & (FLOW_TIMEOUT_REASSEMBLY_DONE | FLOW_ACTION_DROP)) &&
!FlowIsBypassed(f) && FlowForceReassemblyNeedReassembly(f) == 1) {
/* Send the flow to its thread */
FlowForceReassemblyForFlow(f);
Expand Down
14 changes: 9 additions & 5 deletions src/flow-worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "suricata-common.h"
#include "suricata.h"

#include "action-globals.h"
#include "decode.h"
#include "detect.h"
#include "stream-tcp.h"
Expand Down Expand Up @@ -170,8 +171,9 @@ static void CheckWorkQueue(ThreadVars *tv, FlowWorkerThreadData *fw, FlowTimeout
f->flow_end_flags |= FLOW_END_FLAG_TIMEOUT; //TODO emerg

if (f->proto == IPPROTO_TCP) {
if (!(f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE) && !FlowIsBypassed(f) &&
FlowForceReassemblyNeedReassembly(f) == 1 && f->ffr != 0) {
if (!(f->flags & (FLOW_TIMEOUT_REASSEMBLY_DONE | FLOW_ACTION_DROP)) &&
!FlowIsBypassed(f) && FlowForceReassemblyNeedReassembly(f) == 1 &&
f->ffr != 0) {
/* read detect thread in case we're doing a reload */
void *detect_thread = SC_ATOMIC_GET(fw->detect_thread);
int cnt = FlowFinish(tv, f, fw, detect_thread);
Expand Down Expand Up @@ -538,9 +540,11 @@ static TmEcode FlowWorker(ThreadVars *tv, Packet *p, void *data)

/* handle the app layer part of the UDP packet payload */
} else if (p->flow && p->proto == IPPROTO_UDP) {
FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_APPLAYERUDP);
AppLayerHandleUdp(tv, fw->stream_thread->ra_ctx->app_tctx, p, p->flow);
FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_APPLAYERUDP);
if (!PACKET_TEST_ACTION(p, ACTION_DROP)) {
FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_APPLAYERUDP);
AppLayerHandleUdp(tv, fw->stream_thread->ra_ctx->app_tctx, p, p->flow);
FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_APPLAYERUDP);
}
}

PacketUpdateEngineEventCounters(tv, fw->dtv, p);
Expand Down
5 changes: 5 additions & 0 deletions src/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

#include "suricata-common.h"
#include "suricata.h"

#include "action-globals.h"
#include "decode.h"
#include "conf.h"
#include "threadvars.h"
Expand Down Expand Up @@ -473,6 +475,9 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p, ThreadVars *tv, DecodeThreadVars
FlowUpdateState(f, FLOW_STATE_ESTABLISHED);
}

if (f->flags & FLOW_ACTION_DROP) {
PacketDrop(p, ACTION_DROP, PKT_DROP_REASON_FLOW_DROP);
}
/*set the detection bypass flags*/
if (f->flags & FLOW_NOPACKET_INSPECTION) {
SCLogDebug("setting FLOW_NOPACKET_INSPECTION flag on flow %p", f);
Expand Down
4 changes: 4 additions & 0 deletions src/source-windivert.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,12 @@ void *WinDivertGetQueue(int n)
}

// not defined in MinGW winerror.h
#ifndef ERROR_INVALID_IMAGE_HASH
#define ERROR_INVALID_IMAGE_HASH 577L
#endif
#ifndef ERROR_DATA_NOT_ACCEPTED
#define ERROR_DATA_NOT_ACCEPTED 592L
#endif

/**
* \brief return an error description for Win32 error values commonly returned
Expand Down
6 changes: 2 additions & 4 deletions src/stream-tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5107,11 +5107,9 @@ int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
* applayer detection, then drop the rest of the packets of the
* same stream and avoid inspecting it any further */
if (StreamTcpCheckFlowDrops(p) == 1) {
SCLogDebug("This flow/stream triggered a drop rule");
FlowSetNoPacketInspectionFlag(p->flow);
DecodeSetNoPacketInspectionFlag(p);
DEBUG_VALIDATE_BUG_ON(!(PKT_IS_PSEUDOPKT(p)) && !PACKET_TEST_ACTION(p, ACTION_DROP));
SCLogDebug("flow triggered a drop rule");
StreamTcpDisableAppLayer(p->flow);
PacketDrop(p, ACTION_DROP, PKT_DROP_REASON_FLOW_DROP);
/* return the segments to the pool */
StreamTcpSessionPktFree(p);
SCReturnInt(0);
Expand Down
112 changes: 0 additions & 112 deletions src/tests/detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -4794,117 +4794,6 @@ static int SigTestDropFlow03(void)
return result;
}

/** \test test if the engine set flag to drop pkts of a flow that
* triggered a drop action on IDS mode, but continue the inspection
* as usual (instead of on IPS mode) */
static int SigTestDropFlow04(void)
{
Flow f;
HtpState *http_state = NULL;
uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n"
"Cookie: hellocatch\r\n\r\n";
uint32_t http_buf1_len = sizeof(http_buf1) - 1;

uint8_t http_buf2[] = "POST /two HTTP/1.0\r\n"
"User-Agent: Mozilla/1.0\r\n"
"Cookie: hellocatch\r\n\r\n";
uint32_t http_buf2_len = sizeof(http_buf1) - 1;

TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
Signature *s = NULL;
ThreadVars tv;
DetectEngineThreadCtx *det_ctx = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();

memset(&tv, 0, sizeof(ThreadVars));
memset(&f, 0, sizeof(Flow));
memset(&ssn, 0, sizeof(TcpSession));

p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);

FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;

p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;

p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;

StreamTcpInitConfig(TRUE);

DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;

s = DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 "
"(msg:\"Test proto match\"; uricontent:\"one\";"
"sid:1;)");
FAIL_IF_NULL(s);

/* the no inspection flag should be set after the first sig gets triggered,
* so the second packet should not match the next sig (because of no inspection) */
s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any 80 "
"(msg:\"Test proto match\"; uricontent:\"two\";"
"sid:2;)");
FAIL_IF_NULL(s);

SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);

int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
FAIL_IF_NOT(r == 0);

http_state = f.alstate;
FAIL_IF_NULL(http_state);

/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, p1);

FAIL_IF_NOT(PacketAlertCheck(p1, 1));
FAIL_IF(PacketAlertCheck(p1, 2));

FAIL_IF_NOT(p1->flow->flags & FLOW_ACTION_DROP);
FAIL_IF_NOT(PacketTestActionOnRealPkt(p1, ACTION_DROP));

FAIL_IF(p2->flags & PKT_NOPACKET_INSPECTION);

r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
FAIL_IF_NOT(r == 0);

/* do detect */
SigMatchSignatures(&tv, de_ctx, det_ctx, p2);

FAIL_IF(PacketAlertCheck(p2, 1));
FAIL_IF(PacketAlertCheck(p2, 2));
FAIL_IF_NOT(PacketTestActionOnRealPkt(p2, ACTION_DROP));

AppLayerParserThreadCtxFree(alp_tctx);
DetectEngineThreadCtxDeinit(&tv, det_ctx);
DetectEngineCtxFree(de_ctx);

StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);

UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);

PASS;
}

/** \test ICMP packet shouldn't be matching port based sig
* Bug #611 */
static int SigTestPorts01(void)
Expand Down Expand Up @@ -5301,7 +5190,6 @@ void SigRegisterTests(void)
UtRegisterTest("SigTestDropFlow01", SigTestDropFlow01);
UtRegisterTest("SigTestDropFlow02", SigTestDropFlow02);
UtRegisterTest("SigTestDropFlow03", SigTestDropFlow03);
UtRegisterTest("SigTestDropFlow04", SigTestDropFlow04);

UtRegisterTest("DetectAddressYamlParsing01", DetectAddressYamlParsing01);
UtRegisterTest("DetectAddressYamlParsing02", DetectAddressYamlParsing02);
Expand Down