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"
27 #include "detect-engine-buffer.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) {
54  SCLogDebug(
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) {
114  if (s->init_data->list == DETECT_SM_LIST_NOTSET ||
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,
123  s->init_data->transforms.cnt);
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 
157 SigMatch *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 
167 SigMatch *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 }
SignatureInitDataBuffer_::head
SigMatch * head
Definition: detect.h:548
SignatureInitDataBuffer_::sm_init
bool sm_init
Definition: detect.h:540
detect-engine.h
SignatureInitData_::list_set
bool list_set
Definition: detect.h:631
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:155
Signature_::sig_str
char * sig_str
Definition: detect.h:747
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine-buffer.c:157
SigTableElmt_::name
const char * name
Definition: detect.h:1428
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DETECT_SM_LIST_DYNAMIC_START
@ DETECT_SM_LIST_DYNAMIC_START
Definition: detect.h:137
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:931
SIG_FLAG_INIT_FORCE_TOCLIENT
#define SIG_FLAG_INIT_FORCE_TOCLIENT
Definition: detect.h:300
DetectEngineBufferTypeGetNameById
const char * DetectEngineBufferTypeGetNameById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1187
SignatureInitDataBuffer_::multi_capable
bool multi_capable
Definition: detect.h:543
SCDetectBufferSetActiveList
int SCDetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int list)
Definition: detect-engine-buffer.c:29
SignatureInitData_::init_flags
uint32_t init_flags
Definition: detect.h:610
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
SignatureInitData_::buffers_size
uint32_t buffers_size
Definition: detect.h:651
DetectBufferGetLastSigMatch
SigMatch * DetectBufferGetLastSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine-buffer.c:167
DETECT_SM_LIST_BASE64_DATA
@ DETECT_SM_LIST_BASE64_DATA
Definition: detect.h:123
SignatureInitData_::list
int list
Definition: detect.h:630
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:360
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
SignatureInitDataBufferCheckExpand
int SignatureInitDataBufferCheckExpand(Signature *s)
check if buffers array still has space left, expand if not
Definition: detect-parse.c:1976
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:749
DetectEngineTransforms::transforms
TransformData transforms[DETECT_TRANSFORMS_MAX]
Definition: detect.h:416
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:143
SignatureInitDataBuffer_::tail
SigMatch * tail
Definition: detect.h:549
DetectEngineBufferTypeSupportsMultiInstanceGetById
bool DetectEngineBufferTypeSupportsMultiInstanceGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1315
suricata-common.h
SIG_FLAG_INIT_FORCE_TOSERVER
#define SIG_FLAG_INIT_FORCE_TOSERVER
Definition: detect.h:301
SignatureInitData_::curbuf
SignatureInitDataBuffer * curbuf
Definition: detect.h:652
detect-engine-buffer.h
SignatureInitDataBuffer_::only_ts
bool only_ts
Definition: detect.h:546
SignatureInitData_::buffers
SignatureInitDataBuffer * buffers
Definition: detect.h:649
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
detect-parse.h
SignatureInitDataBuffer_::id
uint32_t id
Definition: detect.h:539
Signature_
Signature container.
Definition: detect.h:670
SigMatch_
a single match condition for a signature
Definition: detect.h:356
DETECT_SM_LIST_MAX
@ DETECT_SM_LIST_MAX
Definition: detect.h:134
DetectEngineTransforms::cnt
int cnt
Definition: detect.h:417
SignatureInitDataBuffer_::only_tc
bool only_tc
Definition: detect.h:545
SignatureInitData_::transforms
DetectEngineTransforms transforms
Definition: detect.h:633
SignatureInitDataBuffer_
Definition: detect.h:538
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine-buffer.c:109
SignatureInitData_::buffer_index
uint32_t buffer_index
Definition: detect.h:650
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
DetectEngineBufferTypeGetByIdTransforms
int DetectEngineBufferTypeGetByIdTransforms(DetectEngineCtx *de_ctx, const int id, TransformData *transforms, int transform_cnt)
Definition: detect-engine.c:1773