-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pcap conditional v2.2.6 #6389
Pcap conditional v2.2.6 #6389
Conversation
Add an option to only write to pcap packets with alerts and flow that have alerted.
It will be used later when multiple writing operations will be necessary.
We add a flag to packet to be able to know if this packet was the first one to get alerts on the flow.
This patch optionally adds packet header to the TCP segment and update the for each segment function by changing the callback. This patch is based on the work by Scott Jordan <scottfgjordan@gmail.com>
This patch update the alert mode of pcap logging. It uses the packet header data added to the TCP segments to build packets corresponding to the acked data that did trigger the alert. It then write it to the pcap file before starting to dump all packet for the flow that did alert.
In alert mode, we need to write the root packet to the pcap file instead of the packet that did trigger the alert.
This patch adds the tag as logging condition. If this option is used all tagged packets are written to the pcap.
TCP memory cap was not taking into account the memory that can be used by realloc of Packet headers in TCP segments.
This patch adds a function to get the current pcap file name that will be used to current packet.
This patch updates EVE alerts to add pcap output filename when pcap capture is done in multi mode. In other mode, the pcap file can be determined by checking the timestamps.
This patch updates tcp segment dumping to dump segments from both sides of the session in order when capturing alerts and tags.
We may need to know that a packet has been tagged but is the first one (and thus is not tagged).
We were missing the first packet when using condition pcap logging in tag mode as it was not tagged. As a result we were not getting the stream data triggering the alert in the pcap file.
As Suricata is not supporting pcap-ng we have to stick with one single datalink type for the capture if ever we want to do pcap logging. Assuming this, this patch introduces a function to set the link type globally. This will be used with pcap conditional logging to get the logging of TCP segments with the correct link type.
Set pseudo packet datalink to the global one. This fixes the case where the pcap handle is open with information coming from a pseudo packet. Without this, we did end up in most cases with an Ethernet packet being written in a Raw pcap.
Codecov Report
@@ Coverage Diff @@
## master #6389 +/- ##
==========================================
- Coverage 76.96% 76.92% -0.04%
==========================================
Files 611 612 +1
Lines 186077 186338 +261
==========================================
+ Hits 143214 143344 +130
- Misses 42863 42994 +131
Flags with carried forward coverage won't be shown. Click here to find out more. |
"Pcap logging with multiple link type is not supported."); | ||
} else { | ||
/* In multi mode, only pcap conditional is not supported as a flow timeout | ||
* will trigger packet logging with potentially invalid with. In regular |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first sensor is missing something after with
or should be reworded.
/* Log alerted flow or tagged flow */ | ||
switch (ptd->pcap_log->conditional) { | ||
case LOGMODE_COND_ALERTS: | ||
if (p->alerts.cnt || (p->flow && FlowHasAlerts(p->flow))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could (should?) PKT_FIRST_ALERTS
be used here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be, but isn't necessary. The PKT_FIRST_ALERTS flag is used to determine when the data held in the tcp segments should be dumped (i.e. before the first alerted packet is dumped, otherwise will be out of order). The FlowSetHasAlertsFlag is set in the same block as p->flags |= PKT_FIRST_ALERTS.
SCLogError(SC_ERR_FSEEK, "fseek failed: %s", strerror(errno)); | ||
return TM_ECODE_FAILED; | ||
} | ||
if (fwrite(comp->buffer, 1, out_size, comp->file) < out_size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can out_size
be zero? See conditional at L528.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it can be zero. out_size
is equal to the return of the LZ4F_compressUpdate which is the number of bytes written in to the compression buffer. From the function documentation "@return: number of bytes written into 'dstBuffer' (it can be zero, meaning input data was just buffered) or an error code if it fails".
I don't believe any functionality in this block has actually changed from the original log-pcap.c file, it has just been moved to be within the PcapWrite function rather than the PcapLog function.
MemBufferWriteRaw(pctx->buf, buf, buflen); | ||
|
||
PcapWrite(pctx->pl, pctx->connp, (uint8_t *)pctx->buf->buffer, | ||
seg->pcap_hdr_storage->pktlen + buflen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggst using pctx->pl->h->len
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
#endif | ||
} | ||
if (ret != TM_ECODE_OK) | ||
return ret; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving the pcap log lock held ... need PcapLogUnlock(pl)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also ... missing call (i think?) to PCAPLOG_PROFILE_END()
when returning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks!
@@ -950,6 +1111,12 @@ static TmEcode PcapLogDataInit(ThreadVars *t, const void *initdata, void **data) | |||
|
|||
*data = (void *)td; | |||
|
|||
if (IsTcpSessionDumpingEnabled()) { | |||
td->buf = MemBufferCreateNew(65537); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest a comment for why this is the proper value? Should it be configurable? should it be a #define
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to a define in log-pcap.h, as for the particular value, would need to ask @regit as I am not sure why that was selected versus 65535 which appears to be the common OUTPUT_BUFFER_SIZE defined value in other log- files that call MemBufferCreateNew. Will leave as 65537 for now.
} else if (strcasecmp(s_conditional, "all") != 0) { | ||
SCLogError(SC_ERR_INVALID_ARGUMENT, | ||
"log-pcap: invalid conditional \"%s\". Valid options: \"all\", " | ||
"or \"alerts\" mode ", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tag
is valid too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
pl->conditional = LOGMODE_COND_TAG; | ||
EnableTcpSessionDumping(); | ||
} else if (strcasecmp(s_conditional, "all") != 0) { | ||
SCLogError(SC_ERR_INVALID_ARGUMENT, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest FatalError
here.
* need to check that this is sufficient and allocate more memory if | ||
* not. | ||
*/ | ||
if (GET_PKT_LEN(rp) - p->payload_len > seg->pcap_hdr_storage->alloclen) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest using seg->pcap_hdr_storage->pktlen
here instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and also on L592
Working on addressing feedback ASAP, do you know if there were any QA issues similar to the test ran from the previous PR #6154 (comment) @jlucovsky? I will need to setup a similar test locally to see If I can get to the source of the issue. |
Replaced by: #6408 |
The ConsolidatedDataRow struct had a length field that wasn't truly used. Related to Bug OISF#6389
The `ConsolidatedDataRow` struct had a `length` field that wasn't truly used. Related to Bug OISF#6389
The `ConsolidatedDataRow` struct had a `length` field that wasn't truly used. Related to Bug OISF#6389
Found by oss-fuzz with quadfuzz. Cf https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63113 According to PostgreSQL documentation the maximum number of rows can be the maximum of tuples that can fit onto max u32 pages - 4,294,967,295 (cf https://www.postgresql.org/docs/current/limits.html). Some rough calculations for that indicate that this could go over max u32, so updating the data_row data type to u64. Bug OISF#6389
Found by oss-fuzz with quadfuzz. Cf https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63113 According to PostgreSQL documentation the maximum number of rows can be the maximum of tuples that can fit onto max u32 pages - 4,294,967,295 (cf https://www.postgresql.org/docs/current/limits.html). Some rough calculations for that indicate that this could go over max u32, so updating the data_row data type to u64. Bug OISF#6389
Found by oss-fuzz with quadfuzz. Cf https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63113 According to PostgreSQL documentation the maximum number of rows can be the maximum of tuples that can fit onto max u32 pages - 4,294,967,295 (cf https://www.postgresql.org/docs/current/limits.html). Some rough calculations for that indicate that this could go over max u32, so updating the data_row data type to u64. Bug OISF#6389
Found by oss-fuzz with quadfuzz. Cf https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63113 According to PostgreSQL documentation the maximum number of rows can be the maximum of tuples that can fit onto max u32 pages - 4,294,967,295 (cf https://www.postgresql.org/docs/current/limits.html). Some rough calculations for that indicate that this could go over max u32, so updating the data_row data type to u64. Bug OISF#6389 (cherry picked from commit 8d3de85)
Found by oss-fuzz with quadfuzz. Cf https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=63113 According to PostgreSQL documentation the maximum number of rows can be the maximum of tuples that can fit onto max u32 pages - 4,294,967,295 (cf https://www.postgresql.org/docs/current/limits.html). Some rough calculations for that indicate that this could go over max u32, so updating the data_row data type to u64. Bug OISF#6389 (cherry picked from commit 8d3de85)
Make sure these boxes are signed before submitting your Pull Request -- thank you.
Link to redmine ticket:
Describe changes:
suricata-verify-pr: 542