Skip to content

Commit 718d121

Browse files
authored
Merge pull request #3216 from eduar-hte/inmemory-collection-shared-mutex
Prevent concurrent access to data in InMemoryPerProcess' resolveXXX methods
2 parents 32f6f78 + 4bf9616 commit 718d121

File tree

21 files changed

+329
-214
lines changed

21 files changed

+329
-214
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,11 @@ jobs:
132132
configuration: [Release]
133133
configure:
134134
- {label: "full", opt: "" }
135-
- {label: "wo curl", opt: "-DWITHOUT_CURL=ON" }
136-
- {label: "wo lmdb", opt: "-DWITHOUT_LMDB=ON" }
137-
- {label: "wo lua", opt: "-DWITHOUT_LUA=ON" }
138-
- {label: "wo maxmind", opt: "-DWITHOUT_MAXMIND=ON" }
139-
- {label: "wo libxml", opt: "-WITHOUT_LIBXML2=ON" }
135+
- {label: "wo curl", opt: "-DWITH_CURL=OFF" }
136+
- {label: "wo lua", opt: "-DWITH_LUA=OFF" }
137+
- {label: "wo maxmind", opt: "-DWITH_MAXMIND=OFF" }
138+
- {label: "wo libxml", opt: "-DWITH_LIBXML2=OFF" }
139+
- {label: "with lmdb", opt: "-DWITH_LMDB=ON" }
140140
steps:
141141
- uses: actions/checkout@v4
142142
with:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ ltmain.sh
5050
examples/simple_example_using_c/test
5151
/tools/rules-check/modsec-rules-check
5252
examples/multiprocess_c/multi
53+
examples/multithread/multithread
5354
examples/reading_logs_via_rule_message/simple_request
5455
examples/reading_logs_with_offset/read
5556
examples/using_bodies_in_chunks/simple_request

build/win32/CMakeLists.txt

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ cmake_minimum_required(VERSION 3.24)
22

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

5-
option(WITHOUT_LMDB "Include LMDB support" OFF)
6-
option(WITHOUT_LUA "Include LUA support" OFF)
7-
option(WITHOUT_LIBXML2 "Include LibXML2 support" OFF)
8-
option(WITHOUT_MAXMIND "Include MaxMind support" OFF)
9-
option(WITHOUT_CURL "Include CURL support" OFF)
5+
option(WITH_LMDB "Include LMDB support" OFF)
6+
option(WITH_LUA "Include LUA support" ON)
7+
option(WITH_LIBXML2 "Include LibXML2 support" ON)
8+
option(WITH_MAXMIND "Include MaxMind support" ON)
9+
option(WITH_CURL "Include CURL support" ON)
1010

11-
option(USE_ASAN "Build with Address Sanitizer" OFF)
11+
option(USE_ASAN "Build with Address Sanitizer" OFF)
1212

1313
# common compiler settings
1414

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

9494
macro(enable_feature flag option)
9595
if(${option})
96-
set(${flag} 0)
96+
set(${flag} 1) # ON
9797
else()
98-
set(${flag} 1)
98+
set(${flag} 0) # OFF
9999
endif()
100100
endmacro()
101101

102-
enable_feature(HAVE_LMDB ${WITHOUT_LMDB})
103-
enable_feature(HAVE_LUA ${WITHOUT_LUA})
104-
enable_feature(HAVE_LIBXML2 ${WITHOUT_LIBXML2})
105-
enable_feature(HAVE_MAXMIND ${WITHOUT_MAXMIND})
106-
enable_feature(HAVE_CURL ${WITHOUT_CURL})
102+
enable_feature(HAVE_LMDB ${WITH_LMDB})
103+
enable_feature(HAVE_LUA ${WITH_LUA})
104+
enable_feature(HAVE_LIBXML2 ${WITH_LIBXML2})
105+
enable_feature(HAVE_MAXMIND ${WITH_MAXMIND})
106+
enable_feature(HAVE_CURL ${WITH_CURL})
107107

108108
include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake)
109109

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

112112
find_package(PCRE2 REQUIRED)
113-
find_package(PThreads4W REQUIRED)
114113
find_package(Poco REQUIRED)
115114
find_package(dirent REQUIRED) # used only by tests (check dirent::dirent refernces)
116115

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

140139
target_compile_definitions(libModSecurity PRIVATE WITH_PCRE2)
141140
target_include_directories(libModSecurity PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others ${MBEDTLS_DIR}/include)
142-
target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 pthreads4w::pthreads4w libinjection mbedcrypto Poco::Poco Iphlpapi.lib)
141+
target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 libinjection mbedcrypto Poco::Poco Iphlpapi.lib)
143142

144143
macro(add_package_dependency project compile_definition link_library flag)
145144
if(${flag})
@@ -255,12 +254,15 @@ setExampleTargetProperties(using_bodies_in_chunks)
255254
# reading_logs_via_rule_message
256255
add_executable(reading_logs_via_rule_message ${BASE_DIR}/examples/reading_logs_via_rule_message/simple_request.cc)
257256
setExampleTargetProperties(reading_logs_via_rule_message)
258-
target_link_libraries(reading_logs_via_rule_message PRIVATE libModSecurity pthreads4w::pthreads4w)
259257

260258
# reading_logs_with_offset
261259
add_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc)
262260
setExampleTargetProperties(reading_logs_with_offset)
263261

262+
# multithread
263+
add_executable(multithread ${BASE_DIR}/examples/multithread/multithread.cc)
264+
setExampleTargetProperties(multithread)
265+
264266
# tools
265267
#
266268

build/win32/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Built files will be located in the directory: `build\win32\build\[build_configur
5151
* `using_bodies_in_chunks.exe`
5252
* `reading_logs_via_rule_message.exe`
5353
* `reading_logs_with_offset.exe`
54+
* `multithread.exe`
5455
* Executable files for tools
5556
* `rules_check.exe`
5657

build/win32/conanfile.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
[requires]
22
yajl/2.1.0
33
pcre2/10.42
4-
pthreads4w/3.0.0
54
libxml2/2.12.6
65
lua/5.4.6
76
libcurl/8.6.0

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ AM_COND_IF([EXAMPLES],
423423
examples/Makefile \
424424
examples/simple_example_using_c/Makefile \
425425
examples/multiprocess_c/Makefile \
426+
examples/multithread/Makefile \
426427
examples/reading_logs_with_offset/Makefile \
427428
examples/reading_logs_via_rule_message/Makefile \
428429
examples/using_bodies_in_chunks/Makefile \

examples/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ ACLOCAL_AMFLAGS = -I build
44

55
SUBDIRS = \
66
multiprocess_c \
7+
multithread \
78
reading_logs_with_offset \
89
reading_logs_via_rule_message \
910
simple_example_using_c \

examples/multiprocess_c/Makefile.am

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ multi_LDFLAGS = \
1515
-L$(top_builddir)/src/.libs/ \
1616
$(GEOIP_LDFLAGS) \
1717
-lmodsecurity \
18-
-lpthread \
1918
-lm \
2019
-lstdc++ \
2120
$(LUA_LDFLAGS) \

examples/multithread/Makefile.am

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
2+
3+
noinst_PROGRAMS = multithread
4+
5+
multithread_SOURCES = \
6+
multithread.cc
7+
8+
multithread_LDADD = \
9+
$(CURL_LDADD) \
10+
$(GEOIP_LDADD) \
11+
$(GLOBAL_LDADD) \
12+
$(LIBXML2_LDADD) \
13+
$(LMDB_LDADD) \
14+
$(MAXMIND_LDADD) \
15+
$(LUA_LDADD) \
16+
$(PCRE_LDADD) \
17+
$(SSDEEP_LDADD) \
18+
$(YAJL_LDADD)
19+
20+
multithread_LDFLAGS = \
21+
-L$(top_builddir)/src/.libs/ \
22+
$(GEOIP_LDFLAGS) \
23+
-lmodsecurity \
24+
-lm \
25+
-lstdc++ \
26+
$(LMDB_LDFLAGS) \
27+
$(LUA_LDFLAGS) \
28+
$(MAXMIND_LDFLAGS) \
29+
$(SSDEEP_LDFLAGS) \
30+
$(YAJL_LDFLAGS)
31+
32+
multithread_CPPFLAGS = \
33+
$(GLOBAL_CFLAGS) \
34+
-I$(top_builddir)/headers \
35+
-I$(top_builddir) \
36+
-g \
37+
-I../others \
38+
-fPIC \
39+
-O3 \
40+
$(CURL_CFLAGS) \
41+
$(GEOIP_CFLAGS) \
42+
$(GLOBAL_CPPFLAGS) \
43+
$(MODSEC_NO_LOGS) \
44+
$(YAJL_CFLAGS) \
45+
$(LMDB_CFLAGS) \
46+
$(LUA_CFLAGS) \
47+
$(PCRE_CFLAGS) \
48+
$(LIBXML2_CFLAGS)
49+
50+
51+
MAINTAINERCLEANFILES = \
52+
Makefile.in
53+
54+

examples/multithread/basic_rules.conf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
SecDebugLog debug.log
2+
SecDebugLogLevel 9
3+
4+
5+
SecRule REQUEST_HEADERS:User-Agent ".*" "id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}"
6+
7+
SecAction "id:2,phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}"
8+
9+
SecRule REQUEST_HEADERS:User-Agent "@rx .*" "id:3,phase:2,setvar:ip.auth_attempt=+1"
10+
11+
SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar,expirevar:ip.foo=2"
12+
#SecRule ARGS:foo "@rx herewego" "id:4,phase:2,setvar:ip.foo=bar"
13+
SecRule IP "@rx bar" "id:5,phase:2,pass"
14+
SecRule IP:auth_attempt "@rx bar" "id:6,phase:2,pass"

examples/multithread/multithread.cc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <iostream>
2+
#include <thread>
3+
#include <array>
4+
5+
#include <modsecurity/modsecurity.h>
6+
#include <modsecurity/transaction.h>
7+
#include <modsecurity/rules_set.h>
8+
9+
static void process_request(modsecurity::ModSecurity *modsec, modsecurity::RulesSet *rules, int tid) {
10+
std::cout << "Hello World! It's me, thread #" << tid << std::endl;
11+
12+
for(int i = 0; i != 1'000; i++) {
13+
auto modsecTransaction = std::make_unique<modsecurity::Transaction>(modsec, rules, nullptr);
14+
15+
modsecTransaction->processConnection("127.0.0.1", 12345, "127.0.0.1", 80);
16+
modsecTransaction->processURI(
17+
"https://www.modsecurity.org/test?foo=herewego",
18+
"GET", "1.1");
19+
20+
modsecTransaction->addRequestHeader("User-Agent",
21+
"Basic ModSecurity example");
22+
modsecTransaction->processRequestHeaders();
23+
modsecTransaction->processRequestBody();
24+
25+
modsecTransaction->addResponseHeader("HTTP/1.1",
26+
"200 OK");
27+
modsecTransaction->processResponseHeaders(200, "HTTP 1.2");
28+
modsecTransaction->processResponseBody();
29+
30+
modsecTransaction->processLogging();
31+
32+
std::this_thread::sleep_for(std::chrono::microseconds(100));
33+
}
34+
35+
std::cout << "Thread #" << tid << " exits" << std::endl;
36+
}
37+
38+
int main (int argc, char *argv[]) {
39+
auto modsec = std::make_unique<modsecurity::ModSecurity>();
40+
modsec->setConnectorInformation("ModSecurity-test v0.0.1-alpha (Simple " \
41+
"example on how to use ModSecurity API");
42+
43+
char main_rule_uri[] = "basic_rules.conf";
44+
auto rules = std::make_unique<modsecurity::RulesSet>();
45+
if (rules->loadFromUri(main_rule_uri) < 0) {
46+
std::cerr << "Problems loading the rules..." << std::endl;
47+
std::cerr << rules->m_parserError.str() << std::endl;
48+
return -1;
49+
}
50+
51+
constexpr auto NUM_THREADS = 100;
52+
std::array<std::thread, NUM_THREADS> threads;
53+
54+
for (auto i = 0; i != threads.size(); ++i) {
55+
threads[i] = std::thread(
56+
[&modsec, &rules, i]() {
57+
process_request(modsec.get(), rules.get(), i);
58+
});
59+
}
60+
61+
std::this_thread::sleep_for(std::chrono::microseconds(10000));
62+
63+
for (auto i = 0; i != threads.size(); ++i) {
64+
threads[i].join();
65+
}
66+
67+
return 0;
68+
}

examples/reading_logs_via_rule_message/Makefile.am

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ simple_request_LDFLAGS = \
2121
-L$(top_builddir)/src/.libs/ \
2222
$(GEOIP_LDFLAGS) \
2323
-lmodsecurity \
24-
-lpthread \
2524
-lm \
2625
-lstdc++ \
2726
$(LMDB_LDFLAGS) \

0 commit comments

Comments
 (0)