Skip to content

Prevent concurrent access to data in InMemoryPerProcess' resolveXXX methods #3216

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ jobs:
configuration: [Release]
configure:
- {label: "full", opt: "" }
- {label: "wo curl", opt: "-DWITHOUT_CURL=ON" }
- {label: "wo lmdb", opt: "-DWITHOUT_LMDB=ON" }
- {label: "wo lua", opt: "-DWITHOUT_LUA=ON" }
- {label: "wo maxmind", opt: "-DWITHOUT_MAXMIND=ON" }
- {label: "wo libxml", opt: "-WITHOUT_LIBXML2=ON" }
- {label: "wo curl", opt: "-DWITH_CURL=OFF" }
- {label: "wo lua", opt: "-DWITH_LUA=OFF" }
- {label: "wo maxmind", opt: "-DWITH_MAXMIND=OFF" }
- {label: "wo libxml", opt: "-DWITH_LIBXML2=OFF" }
- {label: "with lmdb", opt: "-DWITH_LMDB=ON" }
steps:
- uses: actions/checkout@v4
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ ltmain.sh
examples/simple_example_using_c/test
/tools/rules-check/modsec-rules-check
examples/multiprocess_c/multi
examples/multithread/multithread
examples/reading_logs_via_rule_message/simple_request
examples/reading_logs_with_offset/read
examples/using_bodies_in_chunks/simple_request
34 changes: 18 additions & 16 deletions build/win32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ cmake_minimum_required(VERSION 3.24)

set(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)

option(WITHOUT_LMDB "Include LMDB support" OFF)
option(WITHOUT_LUA "Include LUA support" OFF)
option(WITHOUT_LIBXML2 "Include LibXML2 support" OFF)
option(WITHOUT_MAXMIND "Include MaxMind support" OFF)
option(WITHOUT_CURL "Include CURL support" OFF)
option(WITH_LMDB "Include LMDB support" OFF)
option(WITH_LUA "Include LUA support" ON)
option(WITH_LIBXML2 "Include LibXML2 support" ON)
option(WITH_MAXMIND "Include MaxMind support" ON)
option(WITH_CURL "Include CURL support" ON)

option(USE_ASAN "Build with Address Sanitizer" OFF)
option(USE_ASAN "Build with Address Sanitizer" OFF)

# common compiler settings

Expand Down Expand Up @@ -93,24 +93,23 @@ set(HAVE_SSDEEP 0) # should always be zero, no conan package available

macro(enable_feature flag option)
if(${option})
set(${flag} 0)
set(${flag} 1) # ON
else()
set(${flag} 1)
set(${flag} 0) # OFF
endif()
endmacro()

enable_feature(HAVE_LMDB ${WITHOUT_LMDB})
enable_feature(HAVE_LUA ${WITHOUT_LUA})
enable_feature(HAVE_LIBXML2 ${WITHOUT_LIBXML2})
enable_feature(HAVE_MAXMIND ${WITHOUT_MAXMIND})
enable_feature(HAVE_CURL ${WITHOUT_CURL})
enable_feature(HAVE_LMDB ${WITH_LMDB})
enable_feature(HAVE_LUA ${WITH_LUA})
enable_feature(HAVE_LIBXML2 ${WITH_LIBXML2})
enable_feature(HAVE_MAXMIND ${WITH_MAXMIND})
enable_feature(HAVE_CURL ${WITH_CURL})

include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake)

configure_file(config.h.cmake ${BASE_DIR}/src/config.h)

find_package(PCRE2 REQUIRED)
find_package(PThreads4W REQUIRED)
find_package(Poco REQUIRED)
find_package(dirent REQUIRED) # used only by tests (check dirent::dirent refernces)

Expand Down Expand Up @@ -139,7 +138,7 @@ add_library(libModSecurity SHARED ${libModSecuritySources})

target_compile_definitions(libModSecurity PRIVATE WITH_PCRE2)
target_include_directories(libModSecurity PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others ${MBEDTLS_DIR}/include)
target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 pthreads4w::pthreads4w libinjection mbedcrypto Poco::Poco Iphlpapi.lib)
target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 libinjection mbedcrypto Poco::Poco Iphlpapi.lib)

macro(add_package_dependency project compile_definition link_library flag)
if(${flag})
Expand Down Expand Up @@ -255,12 +254,15 @@ setExampleTargetProperties(using_bodies_in_chunks)
# reading_logs_via_rule_message
add_executable(reading_logs_via_rule_message ${BASE_DIR}/examples/reading_logs_via_rule_message/simple_request.cc)
setExampleTargetProperties(reading_logs_via_rule_message)
target_link_libraries(reading_logs_via_rule_message PRIVATE libModSecurity pthreads4w::pthreads4w)

# reading_logs_with_offset
add_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc)
setExampleTargetProperties(reading_logs_with_offset)

# multithread
add_executable(multithread ${BASE_DIR}/examples/multithread/multithread.cc)
setExampleTargetProperties(multithread)

# tools
#

Expand Down
1 change: 1 addition & 0 deletions build/win32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Built files will be located in the directory: `build\win32\build\[build_configur
* `using_bodies_in_chunks.exe`
* `reading_logs_via_rule_message.exe`
* `reading_logs_with_offset.exe`
* `multithread.exe`
* Executable files for tools
* `rules_check.exe`

Expand Down
1 change: 0 additions & 1 deletion build/win32/conanfile.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[requires]
yajl/2.1.0
pcre2/10.42
pthreads4w/3.0.0
libxml2/2.12.6
lua/5.4.6
libcurl/8.6.0
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ AM_COND_IF([EXAMPLES],
examples/Makefile \
examples/simple_example_using_c/Makefile \
examples/multiprocess_c/Makefile \
examples/multithread/Makefile \
examples/reading_logs_with_offset/Makefile \
examples/reading_logs_via_rule_message/Makefile \
examples/using_bodies_in_chunks/Makefile \
Expand Down
1 change: 1 addition & 0 deletions examples/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ACLOCAL_AMFLAGS = -I build

SUBDIRS = \
multiprocess_c \
multithread \
reading_logs_with_offset \
reading_logs_via_rule_message \
simple_example_using_c \
Expand Down
1 change: 0 additions & 1 deletion examples/multiprocess_c/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ multi_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
$(GEOIP_LDFLAGS) \
-lmodsecurity \
-lpthread \
-lm \
-lstdc++ \
$(LUA_LDFLAGS) \
Expand Down
54 changes: 54 additions & 0 deletions examples/multithread/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@


noinst_PROGRAMS = multithread

multithread_SOURCES = \
multithread.cc

multithread_LDADD = \
$(CURL_LDADD) \
$(GEOIP_LDADD) \
$(GLOBAL_LDADD) \
$(LIBXML2_LDADD) \
$(LMDB_LDADD) \
$(MAXMIND_LDADD) \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)

multithread_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
$(GEOIP_LDFLAGS) \
-lmodsecurity \
-lm \
-lstdc++ \
$(LMDB_LDFLAGS) \
$(LUA_LDFLAGS) \
$(MAXMIND_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(YAJL_LDFLAGS)

multithread_CPPFLAGS = \
$(GLOBAL_CFLAGS) \
-I$(top_builddir)/headers \
-I$(top_builddir) \
-g \
-I../others \
-fPIC \
-O3 \
$(CURL_CFLAGS) \
$(GEOIP_CFLAGS) \
$(GLOBAL_CPPFLAGS) \
$(MODSEC_NO_LOGS) \
$(YAJL_CFLAGS) \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \
$(LIBXML2_CFLAGS)


MAINTAINERCLEANFILES = \
Makefile.in


14 changes: 14 additions & 0 deletions examples/multithread/basic_rules.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
SecDebugLog debug.log
SecDebugLogLevel 9


SecRule REQUEST_HEADERS:User-Agent ".*" "id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}"

SecAction "id:2,phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}"

SecRule REQUEST_HEADERS:User-Agent "@rx .*" "id:3,phase:2,setvar:ip.auth_attempt=+1"

SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar,expirevar:ip.foo=2"
#SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar"
SecRule IP "@rx bar" "id:5,phase:2,pass"
SecRule IP:auth_attempt "@rx bar" "id:6,phase:2,pass"
68 changes: 68 additions & 0 deletions examples/multithread/multithread.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <iostream>
#include <thread>
#include <array>

#include <modsecurity/modsecurity.h>
#include <modsecurity/transaction.h>
#include <modsecurity/rules_set.h>

static void process_request(modsecurity::ModSecurity *modsec, modsecurity::RulesSet *rules, int tid) {
std::cout << "Hello World! It's me, thread #" << tid << std::endl;

for(int i = 0; i != 1'000; i++) {
auto modsecTransaction = std::make_unique<modsecurity::Transaction>(modsec, rules, nullptr);

modsecTransaction->processConnection("127.0.0.1", 12345, "127.0.0.1", 80);
modsecTransaction->processURI(
"https://www.modsecurity.org/test?foo=herewego",
"GET", "1.1");

modsecTransaction->addRequestHeader("User-Agent",
"Basic ModSecurity example");
modsecTransaction->processRequestHeaders();
modsecTransaction->processRequestBody();

modsecTransaction->addResponseHeader("HTTP/1.1",
"200 OK");
modsecTransaction->processResponseHeaders(200, "HTTP 1.2");
modsecTransaction->processResponseBody();

modsecTransaction->processLogging();

std::this_thread::sleep_for(std::chrono::microseconds(100));
}

std::cout << "Thread #" << tid << " exits" << std::endl;
}

int main (int argc, char *argv[]) {
auto modsec = std::make_unique<modsecurity::ModSecurity>();
modsec->setConnectorInformation("ModSecurity-test v0.0.1-alpha (Simple " \
"example on how to use ModSecurity API");

char main_rule_uri[] = "basic_rules.conf";
auto rules = std::make_unique<modsecurity::RulesSet>();
if (rules->loadFromUri(main_rule_uri) < 0) {
std::cerr << "Problems loading the rules..." << std::endl;
std::cerr << rules->m_parserError.str() << std::endl;
return -1;
}

constexpr auto NUM_THREADS = 100;
std::array<std::thread, NUM_THREADS> threads;

for (auto i = 0; i != threads.size(); ++i) {
threads[i] = std::thread(
[&modsec, &rules, i]() {
process_request(modsec.get(), rules.get(), i);
});
}

std::this_thread::sleep_for(std::chrono::microseconds(10000));

for (auto i = 0; i != threads.size(); ++i) {
threads[i].join();
}

return 0;
}
1 change: 0 additions & 1 deletion examples/reading_logs_via_rule_message/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ simple_request_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
$(GEOIP_LDFLAGS) \
-lmodsecurity \
-lpthread \
-lm \
-lstdc++ \
$(LMDB_LDFLAGS) \
Expand Down
Loading
Loading