suricata
detect-engine-buffer.c
Go to the documentation of this file.
1/* Copyright (C) 2025 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 */
23
24#include "suricata-common.h"
25#include "detect-engine.h"
26#include "detect-parse.h"
28
30{
31 BUG_ON(s->init_data == NULL);
32
34 SCLogError("Rule buffer cannot be reset after base64_data.");
35 return -1;
36 }
37
38 if (s->init_data->list && s->init_data->transforms.cnt) {
39 SCLogError("no matches following transform(s)");
40 return -1;
41 }
42 s->init_data->list = list;
43 s->init_data->list_set = true;
44
45 // check if last has matches -> if no, error
46 if (s->init_data->curbuf && s->init_data->curbuf->head == NULL) {
47 SCLogError("previous sticky buffer has no matches");
48 return -1;
49 }
50
51 for (uint32_t x = 0; x < s->init_data->buffers_size; x++) {
53 for (SigMatch *sm = b->head; sm != NULL; sm = sm->next) {
55 "buf:%p: id:%u: '%s' pos %u", b, b->id, sigmatch_table[sm->type].name, sm->idx);
56 }
57 if ((uint32_t)list == b->id) {
58 SCLogDebug("found buffer %p for list %d", b, list);
59 if (s->init_data->buffers[x].sm_init) {
60 s->init_data->buffers[x].sm_init = false;
61 SCLogDebug("sm_init was true for %p list %d", b, list);
62 s->init_data->curbuf = b;
63 return 0;
64
66 // fall through
67 } else if (!b->only_ts && (s->init_data->init_flags & SIG_FLAG_INIT_FORCE_TOSERVER)) {
68 // fall through
69 } else if (!b->only_tc && (s->init_data->init_flags & SIG_FLAG_INIT_FORCE_TOCLIENT)) {
70 // fall through
71 } else {
72 // we create a new buffer for the same id but forced different direction
73 SCLogWarning("duplicate instance for %s in '%s'",
75 s->init_data->curbuf = b;
76 return 0;
77 }
78 }
79 }
80
81 if (list < DETECT_SM_LIST_MAX)
82 return 0;
83
85 SCLogError("failed to expand rule buffer array");
86 return -1;
87 }
88
89 /* initialize new buffer */
91 s->init_data->curbuf->id = list;
92 s->init_data->curbuf->head = NULL;
93 s->init_data->curbuf->tail = NULL;
97 s->init_data->curbuf->only_tc = true;
98 }
100 s->init_data->curbuf->only_ts = true;
101 }
102
103 SCLogDebug("new: idx %u list %d set up curbuf %p", s->init_data->buffer_index - 1, list,
104 s->init_data->curbuf);
105
106 return 0;
107}
108
110{
111 BUG_ON(s->init_data == NULL);
112
113 if (s->init_data->list && s->init_data->transforms.cnt) {
116 SCLogError("previous transforms not consumed "
117 "(list: %u, transform_cnt %u)",
119 SCReturnInt(-1);
120 }
121
122 SCLogDebug("buffer %d has transform(s) registered: %d", s->init_data->list,
126 if (new_list == -1) {
127 SCReturnInt(-1);
128 }
129 int base_list = s->init_data->list;
130 SCLogDebug("new_list %d", new_list);
131 s->init_data->list = new_list;
132 s->init_data->list_set = false;
133 // reset transforms now that we've set up the list
134 s->init_data->transforms.cnt = 0;
135
136 if (s->init_data->curbuf && s->init_data->curbuf->head != NULL) {
138 SCLogError("failed to expand rule buffer array");
139 return -1;
140 }
144 }
145 if (s->init_data->curbuf == NULL) {
146 SCLogError("failed to setup buffer");
148 SCReturnInt(-1);
149 }
150 s->init_data->curbuf->id = new_list;
151 SCLogDebug("new list after applying transforms: %u", new_list);
152 }
153
154 SCReturnInt(0);
155}
156
157SigMatch *DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
158{
159 for (uint32_t i = 0; i < s->init_data->buffer_index; i++) {
160 if (buf_id == s->init_data->buffers[i].id) {
161 return s->init_data->buffers[i].head;
162 }
163 }
164 return NULL;
165}
166
167SigMatch *DetectBufferGetLastSigMatch(const Signature *s, const uint32_t buf_id)
168{
169 SigMatch *last = NULL;
170 for (uint32_t i = 0; i < s->init_data->buffer_index; i++) {
171 if (buf_id == s->init_data->buffers[i].id) {
172 last = s->init_data->buffers[i].tail;
173 }
174 }
175 return last;
176}
177
178int SCDetectSignatureAddTransform(Signature *s, int transform, void *options)
179{
180 /* we only support buffers */
181 if (s->init_data->list == 0) {
182 SCReturnInt(-1);
183 }
184 if (!s->init_data->list_set) {
185 SCLogError("transforms must directly follow stickybuffers");
186 SCReturnInt(-1);
187 }
189 SCReturnInt(-1);
190 }
191
194
196 SCLogDebug("Added transform #%d [%s]", s->init_data->transforms.cnt, s->sig_str);
197
198 SCReturnInt(0);
199}
int SCDetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
SigMatch * DetectBufferGetLastSigMatch(const Signature *s, const uint32_t buf_id)
int SCDetectSignatureAddTransform(Signature *s, int transform, void *options)
const char * DetectEngineBufferTypeGetNameById(const DetectEngineCtx *de_ctx, const int id)
int DetectEngineBufferTypeGetByIdTransforms(DetectEngineCtx *de_ctx, const int id, TransformData *transforms, int transform_cnt)
bool DetectEngineBufferTypeSupportsMultiInstanceGetById(const DetectEngineCtx *de_ctx, const int id)
int SignatureInitDataBufferCheckExpand(Signature *s)
check if buffers array still has space left, expand if not
SigTableElmt * sigmatch_table
#define SIG_FLAG_INIT_FORCE_TOSERVER
Definition detect.h:302
#define DETECT_SM_LIST_NOTSET
Definition detect.h:144
#define DETECT_TRANSFORMS_MAX
Definition detect.h:48
@ DETECT_SM_LIST_BASE64_DATA
Definition detect.h:124
@ DETECT_SM_LIST_MAX
Definition detect.h:135
@ DETECT_SM_LIST_DYNAMIC_START
Definition detect.h:138
#define SIG_FLAG_INIT_FORCE_TOCLIENT
Definition detect.h:301
DetectEngineCtx * de_ctx
main detection engine ctx
Definition detect.h:932
TransformData transforms[DETECT_TRANSFORMS_MAX]
Definition detect.h:392
a single match condition for a signature
Definition detect.h:356
const char * name
Definition detect.h:1459
uint32_t init_flags
Definition detect.h:608
uint32_t buffers_size
Definition detect.h:649
SignatureInitDataBuffer * buffers
Definition detect.h:647
uint32_t buffer_index
Definition detect.h:648
DetectEngineTransforms transforms
Definition detect.h:631
SignatureInitDataBuffer * curbuf
Definition detect.h:650
Signature container.
Definition detect.h:668
SignatureInitData * init_data
Definition detect.h:747
char * sig_str
Definition detect.h:745
void * options
Definition detect.h:388
#define BUG_ON(x)
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define DEBUG_VALIDATE_BUG_ON(exp)