diff --git a/src/detect-file-data.c b/src/detect-file-data.c index 4ddfdc1583..48e43a394a 100644 --- a/src/detect-file-data.c +++ b/src/detect-file-data.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2020 Open Information Security Foundation +/* Copyright (C) 2007-2021 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -431,19 +431,50 @@ static InspectionBuffer *HttpServerBodyGetDataCallback(DetectEngineThreadCtx *de /* file API based inspection */ +static inline InspectionBuffer *FiledataWithXformsGetDataCallback(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, const int list_id, int local_file_id, + InspectionBuffer *base_buffer, const bool first) +{ + InspectionBufferMultipleForList *fb = InspectionBufferGetMulti(det_ctx, list_id); + InspectionBuffer *buffer = InspectionBufferMultipleForListGet(fb, local_file_id); + if (buffer == NULL) { + SCLogDebug("list_id: %d: no buffer", list_id); + return NULL; + } + if (!first && buffer->inspect != NULL) { + SCLogDebug("list_id: %d: returning %p", list_id, buffer); + return buffer; + } + + InspectionBufferSetup(det_ctx, list_id, buffer, base_buffer->inspect, base_buffer->inspect_len); + buffer->inspect_offset = base_buffer->inspect_offset; + InspectionBufferApplyTransforms(buffer, transforms); + SCLogDebug("xformed buffer %p size %u", buffer, buffer->inspect_len); + SCReturnPtr(buffer, "InspectionBuffer"); +} + static InspectionBuffer *FiledataGetDataCallback(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, - Flow *f, uint8_t flow_flags, File *cur_file, - int list_id, int local_file_id, bool first) + const DetectEngineTransforms *transforms, Flow *f, uint8_t flow_flags, File *cur_file, + const int list_id, const int base_id, int local_file_id, bool first) { SCEnter(); + SCLogDebug( + "starting: list_id %d base_id %d first %s", list_id, base_id, first ? "true" : "false"); - InspectionBufferMultipleForList *fb = InspectionBufferGetMulti(det_ctx, list_id); + InspectionBufferMultipleForList *fb = InspectionBufferGetMulti(det_ctx, base_id); InspectionBuffer *buffer = InspectionBufferMultipleForListGet(fb, local_file_id); + SCLogDebug("base: fb %p buffer %p", fb, buffer); if (buffer == NULL) return NULL; - if (!first && buffer->inspect != NULL) + if (base_id != list_id && buffer->inspect != NULL) { + SCLogDebug("handle xform %s", (list_id != base_id) ? "true" : "false"); + return FiledataWithXformsGetDataCallback( + det_ctx, transforms, list_id, local_file_id, buffer, first); + } + if (!first && buffer->inspect != NULL) { + SCLogDebug("base_id: %d, not first: use %p", base_id, buffer); return buffer; + } const uint64_t file_size = FileDataSize(cur_file); const DetectEngineCtx *de_ctx = det_ctx->de_ctx; @@ -489,16 +520,21 @@ static InspectionBuffer *FiledataGetDataCallback(DetectEngineThreadCtx *det_ctx, "; data_len %" PRIu32 "; file_size %" PRIu64, list_id, buffer->inspect_offset, buffer->inspect_len, data_len, file_size); buffer->inspect_offset = cur_file->content_inspected; - InspectionBufferApplyTransforms(buffer, transforms); - SCLogDebug("[list %d] [after] buffer offset %" PRIu64 "; buffer len %" PRIu32, list_id, - buffer->inspect_offset, buffer->inspect_len); - - SCLogDebug("[list %d] content_inspected %" PRIu64, list_id, cur_file->content_inspected); - SCLogDebug("[list %d] file_data buffer %p, data %p len %u offset %" PRIu64, list_id, buffer, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset); + /* update inspected tracker */ + cur_file->content_inspected = buffer->inspect_len + buffer->inspect_offset; + SCLogDebug("content inspected: %" PRIu64, cur_file->content_inspected); - SCReturnPtr(buffer, "InspectionBuffer"); + /* get buffer for the list id if it is different from the base id */ + if (list_id != base_id) { + SCLogDebug("regular %d has been set up: now handle xforms id %d", base_id, list_id); + InspectionBuffer *tbuffer = FiledataWithXformsGetDataCallback( + det_ctx, transforms, list_id, local_file_id, buffer, first); + SCReturnPtr(tbuffer, "InspectionBuffer"); + } else { + SCLogDebug("regular buffer %p size %u", buffer, buffer->inspect_len); + SCReturnPtr(buffer, "InspectionBuffer"); + } } static int DetectEngineInspectFiledata( @@ -526,8 +562,8 @@ static int DetectEngineInspectFiledata( if (file->txid != tx_id) continue; - InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx, - transforms, f, flags, file, engine->sm_list, local_file_id, false); + InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx, transforms, f, flags, file, + engine->sm_list, engine->sm_list_base, local_file_id, false); if (buffer == NULL) continue; @@ -545,8 +581,6 @@ static int DetectEngineInspectFiledata( buffer->inspect_len, buffer->inspect_offset, ciflags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - /* update inspected tracker */ - file->content_inspected = buffer->inspect_len + buffer->inspect_offset; if (match == 1) { r = 1; break; @@ -562,6 +596,7 @@ static int DetectEngineInspectFiledata( typedef struct PrefilterMpmFiledata { int list_id; + int base_list_id; const MpmCtx *mpm_ctx; const DetectEngineTransforms *transforms; } PrefilterMpmFiledata; @@ -595,8 +630,8 @@ static void PrefilterTxFiledata(DetectEngineThreadCtx *det_ctx, if (file->txid != idx) continue; - InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx, - ctx->transforms, f, flags, file, list_id, local_file_id, true); + InspectionBuffer *buffer = FiledataGetDataCallback(det_ctx, ctx->transforms, f, flags, + file, list_id, ctx->base_list_id, local_file_id, true); if (buffer == NULL) continue; @@ -623,6 +658,7 @@ int PrefilterMpmFiledataRegister(DetectEngineCtx *de_ctx, if (pectx == NULL) return -1; pectx->list_id = list_id; + pectx->base_list_id = mpm_reg->sm_list_base; pectx->mpm_ctx = mpm_ctx; pectx->transforms = &mpm_reg->transforms;