Adds suppor for HyperScan in the bulid system

This commit is contained in:
Felipe Zimmerle 2021-02-26 11:15:02 -03:00
parent 2e69ce6ccf
commit 912704b6d4
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
16 changed files with 291 additions and 23 deletions

176
build/hyperscan.m4 Normal file
View File

@ -0,0 +1,176 @@
dnl Check for HyperScan Libraries
dnl CHECK_YAJL(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
AC_DEFUN([PROG_HS], [
# Needed if pkg-config will be used.
AC_REQUIRE([PKG_PROG_PKG_CONFIG])
# Possible names for the hs library/package (pkg-config)
HS_POSSIBLE_LIB_NAMES="hs libhs"
# Possible extensions for the library
HS_POSSIBLE_EXTENSIONS="so la sl dll dylib"
# Possible paths (if pkg-config was not found, proceed with the file lookup)
HS_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/libhs /usr/local/hyperscan /usr/local /opt/libhs /opt/hs /opt /usr /usr/lib64"
# Variables to be set by this very own script.
HS_VERSION=""
HS_CFLAGS=""
HS_CPPFLAGS=""
HS_LDADD=""
HS_LDFLAGS=""
AC_ARG_WITH(
hyperscan,
AC_HELP_STRING(
[--with-hyperscan=PATH],
[Path to HyperScan prefix or config script]
)
)
if test "x${with_hyperscan}" == "xno"; then
AC_DEFINE(HAVE_HS, 0, [Support for HS was disabled by the utilization of --without-hyperscan or --with-hyperscan=no])
AC_MSG_NOTICE([Support for HyperScan was disabled by the utilization of --without-hyperscan or --with-hyperscan=no])
HS_DISABLED=yes
else
if test "x${with_hyperscan}" == "xyes"; then
HS_MANDATORY=yes
AC_MSG_NOTICE([HyperScan support was marked as mandatory by the utilization of --with-hyperscan=yes])
fi
# for x in ${HS_POSSIBLE_LIB_NAMES}; do
# CHECK_FOR_HS_AT(${x})
# if test -n "${HS_VERSION}"; then
# break
# fi
# done
# if test "x${with_hs}" != "xyes" or test "x${with_hs}" == "xyes"; then
if test "x${with_hyperscan}" == "x" || test "x${with_hyperscan}" == "xyes"; then
# Nothing about HyperScan was informed, using the pkg-config to figure things out.
if test -n "${PKG_CONFIG}"; then
HS_PKG_NAME=""
for x in ${HS_POSSIBLE_LIB_NAMES}; do
if ${PKG_CONFIG} --exists ${x}; then
HS_PKG_NAME="$x"
break
fi
done
fi
AC_MSG_NOTICE([Nothing about HyperScan was informed during the configure phase. Trying to detect it on the platform...])
if test -n "${HS_PKG_NAME}"; then
# Package was found using the pkg-config scripts
HS_VERSION="`${PKG_CONFIG} ${HS_PKG_NAME} --modversion`"
HS_CFLAGS="`${PKG_CONFIG} ${HS_PKG_NAME} --cflags`"
HS_LDADD="`${PKG_CONFIG} ${HS_PKG_NAME} --libs-only-l`"
HS_LDFLAGS="`${PKG_CONFIG} ${HS_PKG_NAME} --libs-only-L --libs-only-other`"
HS_DISPLAY="${HS_LDADD}, ${HS_CFLAGS}"
else
# If pkg-config did not find anything useful, go over file lookup.
for x in ${HS_POSSIBLE_LIB_NAMES}; do
CHECK_FOR_HS_AT(${x})
if test -n "${HS_VERSION}"; then
break
fi
done
fi
fi
if test "x${with_hyperscan}" != "x"; then
# An specific path was informed, lets check.
HS_MANDATORY=yes
CHECK_FOR_HS_AT(${with_hs})
fi
# fi
fi
if test -z "${HS_LDADD}"; then
if test -z "${HS_MANDATORY}"; then
if test -z "${HS_DISABLED}"; then
AC_MSG_NOTICE([HyperScan library was not found])
HS_FOUND=0
else
HS_FOUND=2
fi
else
AC_MSG_ERROR([HyperScan was explicitly referenced but it was not found])
HS_FOUND=-1
fi
else
HS_FOUND=1
AC_MSG_NOTICE([using HyperScan v${HS_VERSION}])
HS_CFLAGS="-DWITH_HS ${HS_CFLAGS}"
HS_DISPLAY="${HS_LDADD}, ${HS_CFLAGS}"
AC_SUBST(HS_VERSION)
AC_SUBST(HS_LDADD)
AC_SUBST(HS_LIBS)
AC_SUBST(HS_LDFLAGS)
AC_SUBST(HS_CFLAGS)
AC_SUBST(HS_DISPLAY)
fi
AC_SUBST(HS_FOUND)
]) # AC_DEFUN [PROG_HS]
AC_DEFUN([CHECK_FOR_HS_AT], [
path=$1
for y in ${HS_POSSIBLE_EXTENSIONS}; do
for z in ${HS_POSSIBLE_LIB_NAMES}; do
if test -e "${path}/${z}.${y}"; then
hs_lib_path="${path}/"
hs_lib_name="${z}"
hs_lib_file="${hs_lib_path}/${z}.${y}"
break
fi
if test -e "${path}/lib${z}.${y}"; then
hs_lib_path="${path}/"
hs_lib_name="${z}"
hs_lib_file="${hs_lib_path}/lib${z}.${y}"
break
fi
if test -e "${path}/lib/lib${z}.${y}"; then
hs_lib_path="${path}/lib/"
hs_lib_name="${z}"
hs_lib_file="${hs_lib_path}/lib${z}.${y}"
break
fi
if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then
hs_lib_path="${path}/lib/x86_64-linux-gnu/"
hs_lib_name="${z}"
hs_lib_file="${hs_lib_path}/lib${z}.${y}"
break
fi
done
if test -n "$hs_lib_path"; then
break
fi
done
if test -e "${path}/include/hs.h"; then
hs_inc_path="${path}/include"
elif test -e "${path}/hs_common.h"; then
hs_inc_path="${path}"
elif test -e "${path}/include/hs/hs.h"; then
hs_inc_path="${path}/include"
fi
if test -n "${hs_lib_path}"; then
AC_MSG_NOTICE([HyperScan library found at: ${hs_lib_file}])
fi
if test -n "${hs_inc_path}"; then
AC_MSG_NOTICE([HyperScan headers found at: ${hs_inc_path}])
fi
if test -n "${hs_lib_path}" -a -n "${hs_inc_path}"; then
# TODO: Compile a piece of code to check the version.
HS_CFLAGS="-I${hs_inc_path}"
HS_LDADD="-l${hs_lib_name}"
HS_LDFLAGS="-L${hs_lib_path}"
HS_DISPLAY="${hs_lib_file}, ${hs_inc_path}"
fi
]) # AC_DEFUN [CHECK_FOR_HS_AT]

View File

@ -78,6 +78,10 @@ AC_DEFUN([LIBINJECTION_VERSION], m4_esyscmd_s(cd "others/libinjection" && git de
# SecLang test version
AC_DEFUN([SECLANG_TEST_VERSION], m4_esyscmd_s(cd "test/test-cases/secrules-language-tests" && git log -1 --format="%h" --abbrev-commit && cd ../../..))
# Check for hyperscan
PROG_HS
AM_CONDITIONAL([HS_VERSION], [test "$HS_VERSION" != ""])
# Check for yajl
PROG_YAJL
@ -553,6 +557,22 @@ if test "x$LUA_FOUND" = "x2"; then
echo " + LUA ....disabled"
fi
## HyperScan
if test "x$HS_FOUND" = "x0"; then
echo " + HyperScan ....not found"
fi
if test "x$HS_FOUND" = "x1"; then
echo -n " + HyperScan ....found "
if ! test "x$HS_VERSION" = "x"; then
echo "v${HS_VERSION}"
else
echo ""
fi
echo " ${HS_DISPLAY}"
fi
if test "x$HS_FOUND" = "x2"; then
echo " + HyperScan ....disabled"
fi
echo " "
echo " Other Options"

View File

@ -9,7 +9,8 @@ multi_LDADD = \
$(SSDEEP_LDADD) \
$(LUA_LDADD) \
$(MAXMIND_LDADD) \
$(GLOBAL_LDADD)
$(GLOBAL_LDADD) \
$(HS_LDADD)
multi_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
@ -21,6 +22,7 @@ multi_LDFLAGS = \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(MAXMIND_LDFLAGS) \
$(HS_LDFLAGS) \
$(YAJL_LDFLAGS)
multi_CFLAGS = \

View File

@ -15,7 +15,8 @@ simple_request_LDADD = \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
$(YAJL_LDADD) \
$(HS_LDADD)
simple_request_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
@ -28,6 +29,7 @@ simple_request_LDFLAGS = \
$(LUA_LDFLAGS) \
$(MAXMIND_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(HS_LDFLAGS) \
$(YAJL_LDFLAGS)
simple_request_CPPFLAGS = \
@ -44,6 +46,7 @@ simple_request_CPPFLAGS = \
$(GLOBAL_CPPFLAGS) \
$(MODSEC_NO_LOGS) \
$(YAJL_CFLAGS) \
$(HS_CFLAGS) \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \

View File

@ -15,6 +15,7 @@ read_LDADD = \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(HS_LDADD) \
$(YAJL_LDADD)
read_LDFLAGS = \
@ -28,6 +29,7 @@ read_LDFLAGS = \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(MAXMIND_LDFLAGS) \
$(HS_LDFLAGS) \
$(YAJL_LDFLAGS)
read_CPPFLAGS = \
@ -48,6 +50,7 @@ read_CPPFLAGS = \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \
$(HS_CFLAGS) \
$(LIBXML2_CFLAGS)

View File

@ -8,6 +8,7 @@ test_SOURCES = \
test_LDADD = \
$(GLOBAL_LDADD) \
$(LUA_LDADD) \
$(HS_LDADD) \
$(SSDEEP_LDADD)
test_LDFLAGS = \
@ -18,6 +19,7 @@ test_LDFLAGS = \
-lstdc++ \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(HS_LDFLAGS) \
$(YAJL_LDFLAGS)
test_CFLAGS = \

View File

@ -15,6 +15,7 @@ simple_request_LDADD = \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(HS_LDADD) \
$(YAJL_LDADD)
simple_request_LDFLAGS = \
@ -29,6 +30,7 @@ simple_request_LDFLAGS = \
-lpthread \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(HS_LDFLAGS) \
$(YAJL_LDFLAGS)
simple_request_CPPFLAGS = \
@ -49,6 +51,7 @@ simple_request_CPPFLAGS = \
$(LMDB_CFLAGS) \
$(LUA_CFLAGS) \
$(PCRE_CFLAGS) \
$(HS_CFLAGS) \
$(LIBXML2_CFLAGS)
MAINTAINERCLEANFILES = \

View File

@ -326,6 +326,7 @@ libmodsecurity_la_CPPFLAGS = \
$(SSDEEP_CFLAGS) \
$(MAXMIND_CFLAGS) \
$(LUA_CFLAGS) \
$(HS_CFLAGS) \
$(LIBXML2_CFLAGS)
@ -341,6 +342,7 @@ libmodsecurity_la_LDFLAGS = \
$(SSDEEP_LDFLAGS) \
$(MAXMIND_LDFLAGS) \
$(YAJL_LDFLAGS) \
$(HS_LDFLAGS) \
-version-info @MSC_VERSION_INFO@
@ -356,5 +358,6 @@ libmodsecurity_la_LIBADD = \
$(PCRE_LDADD) \
$(MAXMIND_LDADD) \
$(SSDEEP_LDADD) \
$(HS_LDADD) \
$(YAJL_LDADD)

View File

@ -25,14 +25,23 @@
#include <list>
#include <memory>
#ifdef WITH_HS
#include <hs.h>
#endif
#include "src/operators/operator.h"
#ifndef WITH_HS
#include "src/utils/acmp.h"
#endif
#include "src/utils/string.h"
namespace modsecurity {
namespace operators {
Pm::~Pm() {
#ifdef WITH_HS
#else
acmp_node_t *root = m_p->root_node;
cleanup(root);
@ -42,9 +51,10 @@ Pm::~Pm() {
#ifdef MODSEC_MUTEX_ON_PM
pthread_mutex_destroy(&m_lock);
#endif
#endif
}
#ifndef WITH_HS
void Pm::cleanup(acmp_node_t *n) {
if (n == NULL) {
return;
@ -67,8 +77,9 @@ void Pm::cleanup(acmp_node_t *n) {
free(n);
}
#endif
#ifndef WITH_HS
void Pm::postOrderTraversal(acmp_btree_node_t *node) {
if (node == NULL) {
return;
@ -79,10 +90,14 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) {
free(node);
}
#endif
bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,
const std::string &input, std::shared_ptr<RuleMessage> ruleMessage) {
#ifdef WITH_HS
return 0;
#else
int rc;
ACMPT pt;
pt.parser = m_p;
@ -110,10 +125,16 @@ bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,
}
return rc >= 0;
#endif
return 0;
}
bool Pm::init(const std::string &file, std::string *error) {
#ifdef WITH_HS
fprintf(stdout, "Sopport for HS is on the way: %s\n", hs_version());
#else
std::vector<std::string> vec;
std::istringstream *iss;
const char *err = NULL;
@ -146,7 +167,7 @@ bool Pm::init(const std::string &file, std::string *error) {
}
delete iss;
#endif
return true;
}

View File

@ -34,11 +34,17 @@ class Pm : public Operator {
/** @ingroup ModSecurity_Operator */
explicit Pm(std::unique_ptr<RunTimeString> param)
: Operator("Pm", std::move(param)) {
#ifdef WITH_HS
#else
m_p = acmp_create(0);
#endif
}
explicit Pm(const std::string &n, std::unique_ptr<RunTimeString> param)
: Operator(n, std::move(param)) {
#ifdef WITH_HS
#else
m_p = acmp_create(0);
#endif
}
~Pm();
bool evaluate(Transaction *transaction, RuleWithActions *rule,
@ -47,17 +53,23 @@ class Pm : public Operator {
bool init(const std::string &file, std::string *error) override;
#ifndef WITH_HS
void postOrderTraversal(acmp_btree_node_t *node);
void cleanup(acmp_node_t *n);
#endif
protected:
#ifndef WITH_HS
ACMP *m_p;
#ifdef MODSEC_MUTEX_ON_PM
#endif
private:
#ifndef WITH_HS
#ifdef MODSEC_MUTEX_ON_PM
pthread_mutex_t m_lock;
#endif
#endif
};

View File

@ -68,13 +68,18 @@ bool PmFromFile::init(const std::string &config, std::string *error) {
for (std::string line; std::getline(*iss, line); ) {
if (isComment(line) == false) {
#ifdef WITH_HS
#else
acmp_add_pattern(m_p, line.c_str(), NULL, NULL, line.length());
#endif
}
}
#ifndef WITH_HS
while (m_p->is_failtree_done == 0) {
acmp_prepare(m_p);
}
#endif
delete iss;
return true;

View File

@ -27,6 +27,7 @@ libmodsec_parser_la_CPPFLAGS = \
$(YAJL_CFLAGS) \
$(LMDB_CFLAGS) \
$(PCRE_CFLAGS) \
$(HS_CFLAGS) \
$(LIBXML2_CFLAGS)
test.cc: seclang-parser.hh

View File

@ -51,7 +51,8 @@ unit_tests_LDADD = \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
$(YAJL_LDADD) \
$(HS_LDADD)
unit_tests_LDFLAGS = \
@ -65,7 +66,8 @@ unit_tests_LDFLAGS = \
$(LMDB_LDFLAGS) \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(YAJL_LDFLAGS)
$(YAJL_LDFLAGS) \
$(HS_LDFLAGS)
unit_tests_CPPFLAGS = \
@ -84,7 +86,8 @@ unit_tests_CPPFLAGS = \
$(YAJL_CFLAGS) \
$(LUA_CFLAGS) \
$(SSDEEP_CFLAGS) \
$(LIBXML2_CFLAGS)
$(LIBXML2_CFLAGS) \
$(HS_CFLAGS)
# regression
@ -105,7 +108,8 @@ regression_tests_LDADD = \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
$(YAJL_LDADD) \
$(HS_LDADD)
regression_tests_LDFLAGS = \
@ -119,7 +123,8 @@ regression_tests_LDFLAGS = \
$(YAJL_LDFLAGS) \
$(LMDB_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(LUA_LDFLAGS)
$(LUA_LDFLAGS) \
$(HS_LDFLAGS)
regression_tests_CPPFLAGS = \
@ -138,7 +143,8 @@ regression_tests_CPPFLAGS = \
$(SSDEEP_CFLAGS) \
$(PCRE_CFLAGS) \
$(YAJL_CFLAGS) \
$(LIBXML2_CFLAGS)
$(LIBXML2_CFLAGS) \
$(HS_CFLAGS)
# optimization
@ -158,7 +164,8 @@ rules_optimization_LDADD = \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
$(YAJL_LDADD) \
$(HS_LDADD)
rules_optimization_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
@ -171,7 +178,8 @@ rules_optimization_LDFLAGS = \
$(LMDB_LDFLAGS) \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(YAJL_LDFLAGS)
$(YAJL_LDFLAGS) \
$(HS_LDFLAGS)
rules_optimization_CPPFLAGS = \
-std=c++11 \
@ -189,5 +197,6 @@ rules_optimization_CPPFLAGS = \
$(SSDEEP_CFLAGS) \
$(PCRE_CFLAGS) \
$(YAJL_CFLAGS) \
$(LIBXML2_CFLAGS)
$(LIBXML2_CFLAGS) \
$(HS_CFLAGS)

View File

@ -15,7 +15,8 @@ benchmark_LDADD = \
$(SSDEEP_LDADD) \
$(LUA_LDADD) \
$(LIBXML2_LDADD) \
$(GLOBAL_LDADD)
$(GLOBAL_LDADD) \
$(HS_LDADD)
benchmark_LDFLAGS = \
-L$(top_builddir)/src/.libs/ \
@ -29,7 +30,8 @@ benchmark_LDFLAGS = \
$(YAJL_LDFLAGS) \
$(LMDB_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(LUA_LDFLAGS)
$(LUA_LDFLAGS) \
$(HS_LDFLAGS)
benchmark_CPPFLAGS = \
-std=c++11 \
@ -37,7 +39,8 @@ benchmark_CPPFLAGS = \
$(GLOBAL_CPPFLAGS) \
$(PCRE_CFLAGS) \
$(LMDB_CFLAGS) \
$(LIBXML2_CFLAGS)
$(LIBXML2_CFLAGS) \
$(HS_CFLAGS)
MAINTAINERCLEANFILES = \
Makefile.in

View File

@ -23,6 +23,7 @@ afl_fuzzer_LDADD = \
$(MAXMIND_LDFLAGS) $(MAXMIND_LDADD) \
$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \
$(LUA_LDFLAGS) $(LUA_LDADD) \
$(HS_LDFLAGS) \
$(LIBXML2_LDADD) \
$(top_builddir)/src/.libs/libmodsecurity.a \
$(top_builddir)/others/libinjection.la \
@ -45,4 +46,5 @@ afl_fuzzer_CPPFLAGS = \
$(YAJL_CFLAGS) \
$(LMDB_CFLAGS) \
$(PCRE_CFLAGS) \
$(LIBXML2_CFLAGS)
$(LIBXML2_CFLAGS) \
$(HS_CFLAGS)

View File

@ -16,7 +16,8 @@ modsec_rules_check_LDADD = \
$(LUA_LDADD) \
$(PCRE_LDADD) \
$(SSDEEP_LDADD) \
$(YAJL_LDADD)
$(YAJL_LDADD) \
$(HS_LDADD)
modsec_rules_check_LDFLAGS = \
$(GEOIP_LDFLAGS) \
@ -25,7 +26,8 @@ modsec_rules_check_LDFLAGS = \
$(LMDB_LDFLAGS) \
$(LUA_LDFLAGS) \
$(SSDEEP_LDFLAGS) \
$(YAJL_LDFLAGS)
$(YAJL_LDFLAGS) \
$(HS_LDFLAGS)
modsec_rules_check_CPPFLAGS = \
-std=c++11 \
@ -34,7 +36,8 @@ modsec_rules_check_CPPFLAGS = \
$(PCRE_CFLAGS) \
$(LMDB_CFLAGS) \
$(MAXMIND_CFLAGS) \
$(LIBXML2_CFLAGS)
$(LIBXML2_CFLAGS) \
$(HS_CFLAGS)
MAINTAINERCLEANFILES = \
Makefile.in