detect: modify AMATCH locking

This is an intrusive change. This patch modifies the way AMATCH
inspection uses locking.

So far, each keyword did it's own locking. This lead to a situation
where a 'alstate' pointer was passed around that was not always
protected by a lock.

This patch moves the locking to the Stateful detection functions.
pull/940/head
Victor Julien 12 years ago
parent 43b6cbd4bc
commit 6e0112d737

@ -91,8 +91,6 @@ static int DetectAppLayerEventAppMatch(ThreadVars *t, DetectEngineThreadCtx *det
int r = 0; int r = 0;
DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx; DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx;
FLOWLOCK_RDLOCK(f);
if (r == 0) { if (r == 0) {
decoder_events = AppLayerParserGetDecoderEvents(f->alparser); decoder_events = AppLayerParserGetDecoderEvents(f->alparser);
if (decoder_events != NULL && if (decoder_events != NULL &&
@ -101,7 +99,6 @@ static int DetectAppLayerEventAppMatch(ThreadVars *t, DetectEngineThreadCtx *det
} }
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(r); SCReturnInt(r);
} }

@ -40,10 +40,8 @@ int DetectAppLayerProtocolMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
int r = 0; int r = 0;
DetectAppLayerProtocolData *data = (DetectAppLayerProtocolData *)m->ctx; DetectAppLayerProtocolData *data = (DetectAppLayerProtocolData *)m->ctx;
FLOWLOCK_RDLOCK(f);
r = (data->negated) ? (f->alproto != data->alproto) : r = (data->negated) ? (f->alproto != data->alproto) :
(f->alproto == data->alproto); (f->alproto == data->alproto);
FLOWLOCK_UNLOCK(f);
return r; return r;
} }

@ -286,8 +286,6 @@ int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
SCReturnInt(0); SCReturnInt(0);
} }
FLOWLOCK_RDLOCK(f);
/* we still haven't seen a request */ /* we still haven't seen a request */
if (!dcerpc_state->dcerpc.dcerpcrequest.first_request_seen) if (!dcerpc_state->dcerpc.dcerpcrequest.first_request_seen)
goto end; goto end;
@ -332,7 +330,6 @@ int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
} }
end: end:
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }

@ -376,35 +376,41 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
} }
} }
sm = s->sm_lists[DETECT_SM_LIST_AMATCH];
KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH); KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH);
for (match = 0; sm != NULL; sm = sm->next) { sm = s->sm_lists[DETECT_SM_LIST_AMATCH];
match = 0; if (sm != NULL) {
if (sigmatch_table[sm->type].AppLayerMatch != NULL) { /* RDLOCK would be nicer, but at least tlsstore needs
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { * write lock currently. */
smb_state = (SMBState *)alstate; FLOWLOCK_WRLOCK(f);
if (smb_state->dcerpc_present) {
for (match = 0; sm != NULL; sm = sm->next) {
match = 0;
if (sigmatch_table[sm->type].AppLayerMatch != NULL) {
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
smb_state = (SMBState *)alstate;
if (smb_state->dcerpc_present) {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
}
} else {
KEYWORD_PROFILING_START; KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type]. match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm); AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0)); KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
} }
} else {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
}
if (match == 0) if (match == 0)
break; break;
if (match == 2) { if (match == 2) {
inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
break; break;
}
} }
} }
} FLOWLOCK_UNLOCK(f);
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
store_de_state = 1; store_de_state = 1;
if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) { if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
if (match == 1) { if (match == 1) {
@ -625,31 +631,38 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
total_matches = 0; total_matches = 0;
KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH); KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH);
for (sm = item->nm; sm != NULL; sm = sm->next) { if (item->nm != NULL) {
if (sigmatch_table[sm->type].AppLayerMatch != NULL) /* RDLOCK would be nicer, but at least tlsstore needs
{ * write lock currently. */
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { FLOWLOCK_WRLOCK(f);
smb_state = (SMBState *)alstate;
if (smb_state->dcerpc_present) { for (sm = item->nm; sm != NULL; sm = sm->next) {
if (sigmatch_table[sm->type].AppLayerMatch != NULL)
{
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
smb_state = (SMBState *)alstate;
if (smb_state->dcerpc_present) {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
}
} else {
KEYWORD_PROFILING_START; KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type]. match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm); AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0)); KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
} }
} else {
KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type].
AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0));
}
if (match == 0) if (match == 0)
break; break;
else if (match == 2) else if (match == 2)
inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
else if (match == 1) else if (match == 1)
total_matches++; total_matches++;
}
} }
FLOWLOCK_UNLOCK(f);
} }
RULE_PROFILING_END(det_ctx, s, match, p); RULE_PROFILING_END(det_ctx, s, match, p);

@ -180,14 +180,12 @@ int DetectFtpbounceALMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
} }
int ret = 0; int ret = 0;
FLOWLOCK_RDLOCK(f);
if (ftp_state->command == FTP_COMMAND_PORT) { if (ftp_state->command == FTP_COMMAND_PORT) {
ret = DetectFtpbounceMatchArgs(ftp_state->port_line, ret = DetectFtpbounceMatchArgs(ftp_state->port_line,
ftp_state->port_line_len, f->src.address.address_un_data32[0], ftp_state->port_line_len, f->src.address.address_un_data32[0],
ftp_state->arg_offset); ftp_state->arg_offset);
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }

@ -126,7 +126,6 @@ int DetectSshVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *
} }
int ret = 0; int ret = 0;
FLOWLOCK_RDLOCK(f);
if ((flags & STREAM_TOCLIENT) && (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { if ((flags & STREAM_TOCLIENT) && (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) {
if (ssh->flags & SSH_FLAG_PROTOVERSION_2_COMPAT) { if (ssh->flags & SSH_FLAG_PROTOVERSION_2_COMPAT) {
SCLogDebug("looking for ssh server protoversion 2 compat"); SCLogDebug("looking for ssh server protoversion 2 compat");
@ -150,7 +149,6 @@ int DetectSshVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *
ret = (strncmp((char *) ssh_state->cli_hdr.proto_version, (char *) ssh->ver, ssh->len) == 0)? 1 : 0; ret = (strncmp((char *) ssh_state->cli_hdr.proto_version, (char *) ssh->ver, ssh->len) == 0)? 1 : 0;
} }
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }

@ -131,7 +131,6 @@ int DetectSshSoftwareVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx
} }
int ret = 0; int ret = 0;
FLOWLOCK_RDLOCK(f);
if ((flags & STREAM_TOCLIENT) && (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { if ((flags & STREAM_TOCLIENT) && (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) {
SCLogDebug("looking for ssh server softwareversion %s length %"PRIu16" on %s", ssh->software_ver, ssh->len, ssh_state->srv_hdr.software_version); SCLogDebug("looking for ssh server softwareversion %s length %"PRIu16" on %s", ssh->software_ver, ssh->len, ssh_state->srv_hdr.software_version);
ret = (strncmp((char *) ssh_state->srv_hdr.software_version, (char *) ssh->software_ver, ssh->len) == 0)? 1 : 0; ret = (strncmp((char *) ssh_state->srv_hdr.software_version, (char *) ssh->software_ver, ssh->len) == 0)? 1 : 0;
@ -139,7 +138,6 @@ int DetectSshSoftwareVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx
SCLogDebug("looking for ssh client softwareversion %s length %"PRIu16" on %s", ssh->software_ver, ssh->len, ssh_state->cli_hdr.software_version); SCLogDebug("looking for ssh client softwareversion %s length %"PRIu16" on %s", ssh->software_ver, ssh->len, ssh_state->cli_hdr.software_version);
ret = (strncmp((char *) ssh_state->cli_hdr.software_version, (char *) ssh->software_ver, ssh->len) == 0)? 1 : 0; ret = (strncmp((char *) ssh_state->cli_hdr.software_version, (char *) ssh->software_ver, ssh->len) == 0)? 1 : 0;
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }

@ -142,8 +142,6 @@ int DetectSslStateMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
return 0; return 0;
} }
FLOWLOCK_RDLOCK(f);
if ((ssd->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) && if ((ssd->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) &&
!(ssl_state->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO)) { !(ssl_state->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO)) {
result = 0; result = 0;
@ -166,7 +164,6 @@ int DetectSslStateMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
} }
end: end:
FLOWLOCK_UNLOCK(f);
return result; return result;
} }

@ -131,8 +131,6 @@ int DetectSslVersionMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
SCReturnInt(0); SCReturnInt(0);
} }
FLOWLOCK_RDLOCK(f);
if (flags & STREAM_TOCLIENT) { if (flags & STREAM_TOCLIENT) {
SCLogDebug("server (toclient) version is 0x%02X", SCLogDebug("server (toclient) version is 0x%02X",
app_state->server_connp.version); app_state->server_connp.version);
@ -143,8 +141,6 @@ int DetectSslVersionMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
ver = app_state->client_connp.version; ver = app_state->client_connp.version;
} }
FLOWLOCK_UNLOCK(f);
switch (ver) { switch (ver) {
case SSL_VERSION_2: case SSL_VERSION_2:
if (ver == ssl->data[SSLv2].ver) if (ver == ssl->data[SSLv2].ver)

@ -125,7 +125,6 @@ int DetectTlsVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *
} }
int ret = 0; int ret = 0;
FLOWLOCK_RDLOCK(f);
SCLogDebug("looking for tls_data->ver 0x%02X (flags 0x%02X)", tls_data->ver, flags); SCLogDebug("looking for tls_data->ver 0x%02X (flags 0x%02X)", tls_data->ver, flags);
if (flags & STREAM_TOCLIENT) { if (flags & STREAM_TOCLIENT) {
@ -137,7 +136,6 @@ int DetectTlsVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *
if (tls_data->ver == ssl_state->client_connp.version) if (tls_data->ver == ssl_state->client_connp.version)
ret = 1; ret = 1;
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }

@ -210,7 +210,6 @@ static int DetectTlsSubjectMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
} }
int ret = 0; int ret = 0;
FLOWLOCK_RDLOCK(f);
SSLStateConnp *connp = NULL; SSLStateConnp *connp = NULL;
if (flags & STREAM_TOSERVER) { if (flags & STREAM_TOSERVER) {
@ -240,8 +239,6 @@ static int DetectTlsSubjectMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
ret = 0; ret = 0;
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }
@ -418,7 +415,6 @@ static int DetectTlsIssuerDNMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx
} }
int ret = 0; int ret = 0;
FLOWLOCK_RDLOCK(f);
SSLStateConnp *connp = NULL; SSLStateConnp *connp = NULL;
if (flags & STREAM_TOSERVER) { if (flags & STREAM_TOSERVER) {
@ -448,8 +444,6 @@ static int DetectTlsIssuerDNMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx
ret = 0; ret = 0;
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }
@ -696,7 +690,6 @@ static int DetectTlsFingerprintMatch (ThreadVars *t, DetectEngineThreadCtx *det_
} }
int ret = 0; int ret = 0;
FLOWLOCK_RDLOCK(f);
if (ssl_state->server_connp.cert0_fingerprint != NULL) { if (ssl_state->server_connp.cert0_fingerprint != NULL) {
SCLogDebug("TLS: Fingerprint is [%s], looking for [%s]\n", SCLogDebug("TLS: Fingerprint is [%s], looking for [%s]\n",
@ -723,8 +716,6 @@ static int DetectTlsFingerprintMatch (ThreadVars *t, DetectEngineThreadCtx *det_
ret = 0; ret = 0;
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(ret); SCReturnInt(ret);
} }
@ -831,6 +822,7 @@ error:
} }
/** \warning modifies state */
static int DetectTlsStoreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) static int DetectTlsStoreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m)
{ {
SCEnter(); SCEnter();
@ -841,12 +833,10 @@ static int DetectTlsStoreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, F
SCReturnInt(1); SCReturnInt(1);
} }
FLOWLOCK_WRLOCK(f);
if (s->flags & SIG_FLAG_TLSSTORE) { if (s->flags & SIG_FLAG_TLSSTORE) {
ssl_state->server_connp.cert_log_flag |= SSL_TLS_LOG_PEM; ssl_state->server_connp.cert_log_flag |= SSL_TLS_LOG_PEM;
} }
FLOWLOCK_UNLOCK(f);
SCReturnInt(1); SCReturnInt(1);
} }

Loading…
Cancel
Save