Skip to content
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

next/639/20241113/v1 #12117

Merged
merged 10 commits into from
Nov 14, 2024
36 changes: 36 additions & 0 deletions etc/schema.json
Original file line number Diff line number Diff line change
@@ -6389,6 +6389,42 @@
"additionalProperties": false
},
"http": {
"type": "object",
"properties": {
"memcap": {
"type": "integer"
},
"memuse": {
"type": "integer"
},
"byterange": {
"type": "object",
"properties": {
"memcap": {
"type": "integer"
},
"memuse": {
"type": "integer"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"host": {
"type": "object",
"properties": {
"memcap": {
"type": "integer"
},
"memuse": {
"type": "integer"
}
},
"additionalProperties": false
},
"ippair": {
"type": "object",
"properties": {
"memcap": {
2 changes: 1 addition & 1 deletion examples/plugins/c-json-filetype/Makefile.in
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

# But as this is an example in the Suricata source tree we'll look for
# includes in the source tree.
CPPFLAGS += -I@top_srcdir@/src -DHAVE_CONFIG_H
CPPFLAGS += -I@top_srcdir@/src -I@top_srcdir@/rust/gen -I@top_srcdir@/rust/dist -DHAVE_CONFIG_H

# Currently the Suricata logging system requires this to be even for
# plugins.
12 changes: 12 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
@@ -317,6 +317,7 @@ noinst_HEADERS = \
feature.h \
flow-bit.h \
flow-bypass.h \
flow-callbacks.h \
flow.h \
flow-hash.h \
flow-manager.h \
@@ -437,6 +438,8 @@ noinst_HEADERS = \
suricata-common.h \
suricata.h \
suricata-plugin.h \
thread-callbacks.h \
thread-storage.h \
threads-debug.h \
threads.h \
threads-profile.h \
@@ -875,6 +878,7 @@ libsuricata_c_a_SOURCES = \
feature.c \
flow-bit.c \
flow-bypass.c \
flow-callbacks.c \
flow.c \
flow-hash.c \
flow-manager.c \
@@ -988,6 +992,8 @@ libsuricata_c_a_SOURCES = \
stream-tcp-sack.c \
stream-tcp-util.c \
suricata.c \
thread-callbacks.c \
thread-storage.c \
threads.c \
tm-modules.c \
tmqh-flow.c \
@@ -1168,6 +1174,12 @@ install-headers:
for header in $(noinst_HEADERS); do \
$(INSTALL_DATA) $$header "$(DESTDIR)${includedir}/suricata"; \
done
if test -e ../rust/dist/rust-bindings.h; then \
$(INSTALL_DATA) ../rust/dist/rust-bindings.h "$(DESTDIR)${includedir}/suricata"; \
fi
if test -e ../rust/gen/rust-bindings.h; then \
$(INSTALL_DATA) ../rust/gen/rust-bindings.h "$(DESTDIR)${includedir}/suricata"; \
fi

# Until we can remove autoconf.h from our headers, we need to to
# provide this for library/plugin users.
10 changes: 10 additions & 0 deletions src/app-layer-ftp.c
Original file line number Diff line number Diff line change
@@ -174,6 +174,16 @@ uint64_t FTPMemcapGlobalCounter(void)
return tmpval;
}

int FTPSetMemcap(uint64_t size)
{
if ((uint64_t)SC_ATOMIC_GET(ftp_memcap) < size) {
SC_ATOMIC_SET(ftp_memcap, size);
return 1;
}

return 0;
}

/**
* \brief Check if alloc'ing "size" would mean we're over memcap
*
1 change: 1 addition & 0 deletions src/app-layer-ftp.h
Original file line number Diff line number Diff line change
@@ -185,6 +185,7 @@ typedef struct FtpDataState_ {
void RegisterFTPParsers(void);
void FTPParserRegisterTests(void);
void FTPParserCleanup(void);
int FTPSetMemcap(uint64_t size);
uint64_t FTPMemuseGlobalCounter(void);
uint64_t FTPMemcapGlobalCounter(void);

24 changes: 23 additions & 1 deletion src/app-layer-htp-range.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2021 Open Information Security Foundation
/* Copyright (C) 2024 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
@@ -42,6 +42,28 @@ static void HttpRangeBlockDerefContainer(HttpRangeContainerBlock *b);

#define CONTAINER_URLRANGE_HASH_SIZE 256

int HTPByteRangeSetMemcap(uint64_t size)
{
if (size == 0 || (uint64_t)SC_ATOMIC_GET(ContainerUrlRangeList.ht->memuse) < size) {
SC_ATOMIC_SET(ContainerUrlRangeList.ht->config.memcap, size);
return 1;
}

return 0;
}

uint64_t HTPByteRangeMemcapGlobalCounter(void)
{
uint64_t tmpval = SC_ATOMIC_GET(ContainerUrlRangeList.ht->config.memcap);
return tmpval;
}

uint64_t HTPByteRangeMemuseGlobalCounter(void)
{
uint64_t tmpval = SC_ATOMIC_GET(ContainerUrlRangeList.ht->memuse);
return tmpval;
}

int HttpRangeContainerBufferCompare(HttpRangeContainerBuffer *a, HttpRangeContainerBuffer *b)
{
// lexical order : start, buflen, offset
6 changes: 5 additions & 1 deletion src/app-layer-htp-range.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2021 Open Information Security Foundation
/* Copyright (C) 2024 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
@@ -111,4 +111,8 @@ HttpRangeContainerBlock *HttpRangeContainerOpenFile(const unsigned char *key, ui

void HttpRangeFreeBlock(HttpRangeContainerBlock *b);

uint64_t HTPByteRangeMemcapGlobalCounter(void);
uint64_t HTPByteRangeMemuseGlobalCounter(void);
int HTPByteRangeSetMemcap(uint64_t);

#endif /* SURICATA_APP_LAYER_HTP_RANGE_H */
7 changes: 7 additions & 0 deletions src/app-layer.c
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
#include "app-layer-protos.h"
#include "app-layer-expectation.h"
#include "app-layer-ftp.h"
#include "app-layer-htp-range.h"
#include "app-layer-detect-proto.h"
#include "app-layer-frames.h"
#include "stream-tcp-reassemble.h"
@@ -1113,6 +1114,12 @@ void AppLayerRegisterGlobalCounters(void)
StatsRegisterGlobalCounter("ftp.memuse", FTPMemuseGlobalCounter);
StatsRegisterGlobalCounter("ftp.memcap", FTPMemcapGlobalCounter);
StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
StatsRegisterGlobalCounter("http.byterange.memuse", HTPByteRangeMemuseGlobalCounter);
StatsRegisterGlobalCounter("http.byterange.memcap", HTPByteRangeMemcapGlobalCounter);
StatsRegisterGlobalCounter("ippair.memuse", IPPairGetMemuse);
StatsRegisterGlobalCounter("ippair.memcap", IPPairGetMemuse);
StatsRegisterGlobalCounter("host.memuse", HostGetMemuse);
StatsRegisterGlobalCounter("host.memcap", HostGetMemcap);
}

static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
6 changes: 4 additions & 2 deletions src/detect-engine-register.c
Original file line number Diff line number Diff line change
@@ -439,18 +439,20 @@ void SigTableCleanup(void)
}
}

void SigTableSetup(void)
void SigTableInit(void)
{
if (sigmatch_table == NULL) {
DETECT_TBLSIZE = DETECT_TBLSIZE_STATIC + DETECT_TBLSIZE_STEP;
sigmatch_table = SCCalloc(DETECT_TBLSIZE, sizeof(SigTableElmt));
if (sigmatch_table == NULL) {
DETECT_TBLSIZE = 0;
FatalError("Could not allocate sigmatch_table");
return;
}
}
}

void SigTableSetup(void)
{
DetectSidRegister();
DetectPriorityRegister();
DetectPrefilterRegister();
1 change: 1 addition & 0 deletions src/detect-engine-register.h
Original file line number Diff line number Diff line change
@@ -338,6 +338,7 @@ extern int DETECT_TBLSIZE_IDX;
#define DETECT_TBLSIZE_STEP 256
int SigTableList(const char *keyword);
void SigTableCleanup(void);
void SigTableInit(void);
void SigTableSetup(void);
void SigTableRegisterTests(void);

129 changes: 129 additions & 0 deletions src/flow-callbacks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/* Copyright (C) 2024 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
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/

#include "flow-callbacks.h"

typedef struct FlowInitCallback_ {
SCFlowInitCallbackFn Callback;
void *user;
struct FlowInitCallback_ *next;
} FlowInitCallback;

static FlowInitCallback *init_callbacks = NULL;

typedef struct FlowUpdateCallback_ {
SCFlowUpdateCallbackFn Callback;
void *user;
struct FlowUpdateCallback_ *next;
} FlowUpdateCallback;

static FlowUpdateCallback *update_callbacks = NULL;

typedef struct FlowFinishCallback_ {
SCFlowFinishCallbackFn Callback;
void *user;
struct FlowFinishCallback_ *next;
} FlowFinishCallback;

static FlowFinishCallback *finish_callbacks = NULL;

bool SCFlowRegisterInitCallback(SCFlowInitCallbackFn fn, void *user)
{
FlowInitCallback *cb = SCCalloc(1, sizeof(*cb));
if (cb == NULL) {
return false;
}
cb->Callback = fn;
cb->user = user;
if (init_callbacks == NULL) {
init_callbacks = cb;
} else {
FlowInitCallback *current = init_callbacks;
while (current->next != NULL) {
current = current->next;
}
current->next = cb;
}
return true;
}

void SCFlowRunInitCallbacks(ThreadVars *tv, Flow *f, const Packet *p)
{
FlowInitCallback *cb = init_callbacks;
while (cb != NULL) {
cb->Callback(tv, f, p, cb->user);
cb = cb->next;
}
}

bool SCFlowRegisterUpdateCallback(SCFlowUpdateCallbackFn fn, void *user)
{
FlowUpdateCallback *cb = SCCalloc(1, sizeof(*cb));
if (cb == NULL) {
return false;
}
cb->Callback = fn;
cb->user = user;
if (update_callbacks == NULL) {
update_callbacks = cb;
} else {
FlowUpdateCallback *current = update_callbacks;
while (current->next != NULL) {
current = current->next;
}
current->next = cb;
}
return true;
}

void SCFlowRunUpdateCallbacks(ThreadVars *tv, Flow *f, Packet *p)
{
FlowUpdateCallback *cb = update_callbacks;
while (cb != NULL) {
cb->Callback(tv, f, p, cb->user);
cb = cb->next;
}
}

bool SCFlowRegisterFinishCallback(SCFlowFinishCallbackFn fn, void *user)
{
FlowFinishCallback *cb = SCCalloc(1, sizeof(*cb));
if (cb == NULL) {
return false;
}
cb->Callback = fn;
cb->user = user;
if (finish_callbacks == NULL) {
finish_callbacks = cb;
} else {
FlowFinishCallback *current = finish_callbacks;
while (current->next != NULL) {
current = current->next;
}
current->next = cb;
}
return true;
}

void SCFlowRunFinishCallbacks(ThreadVars *tv, Flow *f)
{
FlowFinishCallback *cb = finish_callbacks;
while (cb != NULL) {
cb->Callback(tv, f, cb->user);
cb = cb->next;
}
}
Loading