Bug#856640: unblock: suricata/3.2.1-1
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package suricata
The 3.2.1 release includes lots of bugfixes and some of them were direct
security threats (debian security team is already in knowedge of them), which
are special important in security-realted software.
By now, I don't consider updating stretch with only the cherrypicked upstream
commits related to the security issues.
The suricata package is a key package in security related tasks, like an
antivirus, it has to be very updated to stay useful. Thats why I'm asking
for a rather large unblock at this point in the release cycle.
We currently maintain suricata heavily using stable-backports due to this
reason.
The new package is living in experimental and has not been uploaded to unstable
yet.
I'm attaching the debdiff due to it being a bit large.
The debdiff was generated this way:
% debdiff suricata_3.2-2.dsc suricata_3.2.1-1~exp2.dsc
The diffstat follows:
% cat suricata_debdiff.diff | diffstat
ChangeLog | 33
config.h.in | 6
configure | 94 +-
configure.ac | 76 +-
debian/changelog | 15
debian/control | 18
debian/patches/optional-hyperscan.patch | 21
debian/patches/series | 1
debian/rules | 40 -
debian/suricata-hyperscan.install | 3
debian/suricata-hyperscan.postinst | 8
debian/suricata-hyperscan.prerm | 21
debian/suricata.init | 5
debian/suricata.install | 6
debian/suricata.postinst | 8
debian/suricata.preinst | 11
debian/suricata.prerm | 21
doc/userguide/capture-hardware/index.rst | 1
doc/userguide/capture-hardware/napatech.rst | 215 +++++
doc/userguide/output/lua-output.rst | 16
doc/userguide/rules/dnp3-keywords.rst | 2
doc/userguide/rules/index.rst | 1
doc/userguide/rules/tls-keywords.rst | 12
doc/userguide/rules/xbits.rst | 48 +
doc/userguide/suricata.1 | 2
rules/tls-events.rules | 3
scripts/suricatasc/Makefile.in | 2
src/Makefile.am | 1
src/Makefile.in | 30
src/alert-prelude.c | 5
src/app-layer-dcerpc.c | 26
src/app-layer-detect-proto.c | 107 +-
src/app-layer-detect-proto.h | 6
src/app-layer-dnp3.c | 6
src/app-layer-dns-common.c | 5
src/app-layer-dns-tcp.c | 34
src/app-layer-dns-udp.c | 11
src/app-layer-enip.c | 18
src/app-layer-htp-file.c | 4
src/app-layer-htp.c | 4
src/app-layer-modbus.c | 8
src/app-layer-parser.c | 33
src/app-layer-parser.h | 6
src/app-layer-smb.c | 34
src/app-layer-smtp.c | 16
src/app-layer-ssl.c | 24
src/app-layer-ssl.h | 6
src/app-layer-template.c | 6
src/decode-afl.c | 167 ++++
src/decode-icmpv6.c | 141 +++
src/decode-icmpv6.h | 23
src/decode.c | 49 -
src/decode.h | 8
src/defrag-hash.c | 2
src/defrag.c | 170 ++--
src/defrag.h | 2
src/detect-app-layer-event.c | 14
src/detect-csum.c | 2
src/detect-dns-query.c | 14
src/detect-engine-address.c | 5
src/detect-engine-alert.c | 6
src/detect-engine-file.c | 2
src/detect-engine-filedata-smtp.c | 4
src/detect-engine-mpm.c | 2
src/detect-engine-payload.c | 68 -
src/detect-engine-siggroup.c | 50 -
src/detect-engine-tls.c | 6
src/detect-engine.c | 2
src/detect-filemagic.c | 32
src/detect-filemagic.h | 5
src/detect-filesize.c | 2
src/detect-http-header.c | 2
src/detect-ipproto.c | 4
src/detect-parse.c | 6
src/detect-tls-cert-issuer.c | 3
src/detect-tls-cert-subject.c | 3
src/detect-tls-sni.c | 5
src/detect-xbits.c | 215 +++--
src/detect-xbits.h | 2
src/detect.c | 11
src/detect.h | 6
src/flow.c | 24
src/flow.h | 5
src/host-bit.c | 1
src/log-dnslog.c | 68 +
src/log-file.c | 6
src/log-filestore.c | 5
src/log-pcap.c | 7
src/log-tlsstore.c | 5
src/output-file.c | 4
src/output-filedata.c | 5
src/output-json-dns.c | 4
src/output-json-file.c | 4
src/output-json-flow.c | 2
src/output-json-template.c | 3
src/output-tx.c | 40 -
src/queue.h | 12
src/runmode-unittests.c | 141 +--
src/runmode-unix-socket.c | 129 +--
src/runmodes.c | 9
src/source-af-packet.c | 64 +
src/stream-tcp-reassemble.c | 27
src/suricata-common.h | 31
src/suricata.c | 1018 +++++++++++++++-------------
src/suricata.h | 8
src/tm-threads.c | 65 +
src/unix-manager.c | 83 +-
src/unix-manager.h | 2
src/util-debug.c | 68 -
src/util-decode-mime.c | 6
src/util-error.c | 2
src/util-error.h | 2
src/util-file.c | 52 +
src/util-file.h | 6
src/util-logopenfile.c | 13
src/util-lua-common.c | 43 +
src/util-lua-dns.c | 10
src/util-magic.c | 8
src/util-magic.h | 4
src/util-mpm-ac-bs.c | 4
src/util-mpm-ac.c | 44 -
src/util-mpm-hs.c | 5
src/util-mpm.c | 36
src/util-mpm.h | 13
src/util-privs.c | 1
src/util-profiling-keywords.c | 10
src/util-profiling-rulegroups.c | 10
src/util-profiling-rules.c | 10
src/util-profiling.c | 27
src/util-spm.c | 26
src/util-var.c | 2
src/util-var.h | 2
suricata.yaml.in | 11
133 files changed, 2717 insertions(+), 1582 deletions(-)
unblock suricata/3.2.1-1
diff -Nru suricata-3.2/ChangeLog suricata-3.2.1/ChangeLog
--- suricata-3.2/ChangeLog 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/ChangeLog 2017-02-15 08:54:12.000000000 +0100
@@ -1,3 +1,36 @@
+3.2.1 -- 2017-02-15
+
+Feature #1951: Allow building without libmagic/file
+Feature #1972: SURICATA ICMPv6 unknown type 143 for MLDv2 report
+Feature #2010: Suricata should confirm SSSE3 presence at runtime when built with Hyperscan support
+Bug #467: compilation with unittests & debug validation
+Bug #1780: VLAN tags not forwarded in afpacket inline mode
+Bug #1827: Mpm AC fails to alloc memory
+Bug #1843: Mpm Ac: int overflow during init
+Bug #1887: pcap-log sets snaplen to -1
+Bug #1946: can't get response info in some situation
+Bug #1973: suricata fails to start because of unix socket
+Bug #1975: hostbits/xbits memory leak
+Bug #1982: tls: invalid record event triggers on valid traffic
+Bug #1984: http: protocol detection issue if both sides are malformed
+Bug #1985: pcap-log: minor memory leaks
+Bug #1987: log-pcap: pcap files created with invalid snaplen
+Bug #1988: tls_cert_subject bug
+Bug #1989: SMTP protocol detection is case sensitive
+Bug #1991: Suricata cannot parse ports: "![1234, 1235]"
+Bug #1997: tls-store: bug that cause Suricata to crash
+Bug #2001: Handling of unsolicited DNS responses.
+Bug #2003: BUG_ON body sometimes contains side-effectual code
+Bug #2004: Invalid file hash computation when force-hash is used
+Bug #2005: Incoherent sizes between request, capture and http length
+Bug #2007: smb: protocol detection just checks toserver
+Bug #2008: Suricata 3.2, pcap-log no longer works due to timestamp_pattern PCRE
+Bug #2009: Suricata is unable to get offloading settings when run under non-root
+Bug #2012: dns.log does not log unanswered queries
+Bug #2017: EVE Log Missing Fields
+Bug #2019: IPv4 defrag evasion issue
+Bug #2022: dns: out of bound memory read
+
3.2 -- 2016-12-01
Bug #1117: PCAP file count does not persist
diff -Nru suricata-3.2/config.h.in suricata-3.2.1/config.h.in
--- suricata-3.2/config.h.in 2016-11-29 18:17:03.000000000 +0100
+++ suricata-3.2.1/config.h.in 2017-02-15 08:54:30.000000000 +0100
@@ -90,6 +90,9 @@
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
+/* Define to 1 if you have the `hs_valid_platform' function. */
+#undef HAVE_HS_VALID_PLATFORM
+
/* Assuming htp_config_set_response_decompression_layer_limit function in
bundled libhtp */
#undef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
@@ -222,6 +225,9 @@
/* libluajit available */
#undef HAVE_LUAJIT
+/* (Libmagic for file handling) */
+#undef HAVE_MAGIC
+
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
diff -Nru suricata-3.2/configure suricata-3.2.1/configure
--- suricata-3.2/configure 2016-11-29 18:17:03.000000000 +0100
+++ suricata-3.2.1/configure 2017-02-15 08:54:30.000000000 +0100
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for suricata 3.2.
+# Generated by GNU Autoconf 2.69 for suricata 3.2.1.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -643,8 +643,8 @@
# Identity of this package.
PACKAGE_NAME='suricata'
PACKAGE_TARNAME='suricata'
-PACKAGE_VERSION='3.2'
-PACKAGE_STRING='suricata 3.2'
+PACKAGE_VERSION='3.2.1'
+PACKAGE_STRING='suricata 3.2.1'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -977,6 +977,7 @@
with_libnspr_libraries
with_libnss_includes
with_libnss_libraries
+enable_libmagic
with_libmagic_includes
with_libmagic_libraries
enable_napatech
@@ -1580,7 +1581,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures suricata 3.2 to adapt to many kinds of systems.
+\`configure' configures suricata 3.2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1651,7 +1652,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of suricata 3.2:";;
+ short | recursive ) echo "Configuration of suricata 3.2.1:";;
esac
cat <<\_ACEOF
@@ -1701,6 +1702,7 @@
htp
--enable-cuda Enable experimental CUDA pattern matching
--enable-dag Enable DAG capture
+ --enable-libmagic Enable libmagic support [default=yes]
--enable-napatech Enabled Napatech Devices
--enable-lua Enable Lua support
--enable-luajit Enable Luajit support
@@ -1890,7 +1892,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-suricata configure 3.2
+suricata configure 3.2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2355,7 +2357,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by suricata $as_me 3.2, which was
+It was created by suricata $as_me 3.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3223,7 +3225,7 @@
# Define the identity of the package.
PACKAGE='suricata'
- VERSION='3.2'
+ VERSION='3.2.1'
cat >>confdefs.h <<_ACEOF
@@ -15474,9 +15476,13 @@
if test "x$enable_debug_validation" = "xyes"; then :
+ if test "$enable_unittests" = "yes"; then
+ as_fn_error $? "debug_validation can't be enabled with enabled unittests!" "$LINENO" 5
+ else
$as_echo "#define DEBUG_VALIDATION 1" >>confdefs.h
+ fi
fi
@@ -16197,6 +16203,17 @@
HYPERSCAN="no"
fi
+ for ac_func in hs_valid_platform
+do :
+ ac_fn_c_check_func "$LINENO" "hs_valid_platform" "ac_cv_func_hs_valid_platform"
+if test "x$ac_cv_func_hs_valid_platform" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_HS_VALID_PLATFORM 1
+_ACEOF
+
+fi
+done
+
enable_hyperscan="yes"
if test "$HYPERSCAN" = "no"; then
echo
@@ -19842,6 +19859,15 @@
fi
# libmagic
+ enable_magic="no"
+ # Check whether --enable-libmagic was given.
+if test "${enable_libmagic+set}" = set; then :
+ enableval=$enable_libmagic;
+else
+ enable_magic=yes
+fi
+
+ if test "$enable_magic" = "yes"; then
# Check whether --with-libmagic_includes was given.
if test "${with_libmagic_includes+set}" = set; then :
@@ -19859,25 +19885,21 @@
fi
- if test "$with_libmagic_includes" != "no"; then
- CPPFLAGS="${CPPFLAGS} -I${with_libmagic_includes}"
- fi
+ if test "$with_libmagic_includes" != "no"; then
+ CPPFLAGS="${CPPFLAGS} -I${with_libmagic_includes}"
+ fi
- ac_fn_c_check_header_mongrel "$LINENO" "magic.h" "ac_cv_header_magic_h" "$ac_includes_default"
+ ac_fn_c_check_header_mongrel "$LINENO" "magic.h" "ac_cv_header_magic_h" "$ac_includes_default"
if test "x$ac_cv_header_magic_h" = xyes; then :
else
- as_fn_error $? "magic.h not found ..." "$LINENO" 5
+ MAGIC="no"
fi
-
- if test "$with_libmagic_libraries" != "no"; then
- LDFLAGS="${LDFLAGS} -L${with_libmagic_libraries}"
- fi
-
- MAGIC=""
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for magic_open in -lmagic" >&5
+ if test "$MAGIC" != "no"; then
+ MAGIC=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for magic_open in -lmagic" >&5
$as_echo_n "checking for magic_open in -lmagic... " >&6; }
if ${ac_cv_lib_magic_magic_open+:} false; then :
$as_echo_n "(cached) " >&6
@@ -19924,16 +19946,25 @@
MAGIC="no"
fi
+ fi
- if test "$MAGIC" = "no"; then
- echo
- echo " ERROR! magic library not found, go get it"
- echo " from http://www.darwinsys.com/file/ or your distribution:"
- echo
- echo " Ubuntu: apt-get install libmagic-dev"
- echo " Fedora: yum install file-devel"
- echo
- exit 1
+ if test "x$MAGIC" != "xno"; then
+ if test "$with_libmagic_libraries" != "no"; then
+ LDFLAGS="${LDFLAGS} -L${with_libmagic_libraries}"
+ fi
+
+$as_echo "#define HAVE_MAGIC 1" >>confdefs.h
+
+ else
+ echo
+ echo " WARNING! magic library not found, go get it"
+ echo " from http://www.darwinsys.com/file/ or your distribution:"
+ echo
+ echo " Ubuntu: apt-get install libmagic-dev"
+ echo " Fedora: yum install file-devel"
+ echo
+ enable_magic="no"
+ fi
fi
# Napatech - Using the 3GD API
@@ -23963,7 +23994,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by suricata $as_me 3.2, which was
+This file was extended by suricata $as_me 3.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -24029,7 +24060,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-suricata config.status 3.2
+suricata config.status 3.2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -25888,6 +25919,7 @@
Unix socket enabled: ${enable_unixsocket}
Detection enabled: ${enable_detection}
+ Libmagic support: ${enable_magic}
libnss support: ${enable_nss}
libnspr support: ${enable_nspr}
libjansson support: ${enable_jansson}
diff -Nru suricata-3.2/configure.ac suricata-3.2.1/configure.ac
--- suricata-3.2/configure.ac 2016-11-29 18:16:48.000000000 +0100
+++ suricata-3.2.1/configure.ac 2017-02-15 08:54:17.000000000 +0100
@@ -1,4 +1,4 @@
- AC_INIT(suricata, 3.2)
+ AC_INIT(suricata, 3.2.1)
m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])AM_SILENT_RULES([yes])
m4_ifndef([AS_VERSION_COMPARE], [AC_DEFUN([AS_VERSION_COMPARE],[])])
AC_CONFIG_HEADERS([config.h])
@@ -396,7 +396,11 @@
AC_ARG_ENABLE(debug-validation,
AS_HELP_STRING([--enable-debug-validation], [Enable (debug) validation code output]),,[enable_debug_validation=no])
AS_IF([test "x$enable_debug_validation" = "xyes"], [
- AC_DEFINE([DEBUG_VALIDATION],[1],[Enable (debug) validation code output])
+ if test "$enable_unittests" = "yes"; then
+ AC_MSG_ERROR([debug_validation can't be enabled with enabled unittests!])
+ else
+ AC_DEFINE([DEBUG_VALIDATION],[1],[Enable (debug) validation code output])
+ fi
])
# profiling support
@@ -619,6 +623,7 @@
fi
AC_CHECK_LIB(hs,hs_compile,,HYPERSCAN="no")
+ AC_CHECK_FUNCS(hs_valid_platform)
enable_hyperscan="yes"
if test "$HYPERSCAN" = "no"; then
echo
@@ -1555,35 +1560,43 @@
fi
# libmagic
- AC_ARG_WITH(libmagic_includes,
- [ --with-libmagic-includes=DIR libmagic include directory],
- [with_libmagic_includes="$withval"],[with_libmagic_includes=no])
- AC_ARG_WITH(libmagic_libraries,
- [ --with-libmagic-libraries=DIR libmagic library directory],
- [with_libmagic_libraries="$withval"],[with_libmagic_libraries="no"])
-
- if test "$with_libmagic_includes" != "no"; then
- CPPFLAGS="${CPPFLAGS} -I${with_libmagic_includes}"
- fi
-
- AC_CHECK_HEADER(magic.h,,[AC_ERROR(magic.h not found ...)])
-
- if test "$with_libmagic_libraries" != "no"; then
- LDFLAGS="${LDFLAGS} -L${with_libmagic_libraries}"
- fi
-
- MAGIC=""
- AC_CHECK_LIB(magic, magic_open,, MAGIC="no")
-
- if test "$MAGIC" = "no"; then
- echo
- echo " ERROR! magic library not found, go get it"
- echo " from http://www.darwinsys.com/file/ or your distribution:"
- echo
- echo " Ubuntu: apt-get install libmagic-dev"
- echo " Fedora: yum install file-devel"
- echo
- exit 1
+ enable_magic="no"
+ AC_ARG_ENABLE(libmagic,
+ AS_HELP_STRING([--enable-libmagic], [Enable libmagic support [default=yes]]),
+ ,[enable_magic=yes])
+ if test "$enable_magic" = "yes"; then
+ AC_ARG_WITH(libmagic_includes,
+ [ --with-libmagic-includes=DIR libmagic include directory],
+ [with_libmagic_includes="$withval"],[with_libmagic_includes=no])
+ AC_ARG_WITH(libmagic_libraries,
+ [ --with-libmagic-libraries=DIR libmagic library directory],
+ [with_libmagic_libraries="$withval"],[with_libmagic_libraries="no"])
+
+ if test "$with_libmagic_includes" != "no"; then
+ CPPFLAGS="${CPPFLAGS} -I${with_libmagic_includes}"
+ fi
+
+ AC_CHECK_HEADER(magic.h,,MAGIC="no")
+ if test "$MAGIC" != "no"; then
+ MAGIC=""
+ AC_CHECK_LIB(magic, magic_open,, MAGIC="no")
+ fi
+
+ if test "x$MAGIC" != "xno"; then
+ if test "$with_libmagic_libraries" != "no"; then
+ LDFLAGS="${LDFLAGS} -L${with_libmagic_libraries}"
+ fi
+ AC_DEFINE([HAVE_MAGIC],[1],(Libmagic for file handling))
+ else
+ echo
+ echo " WARNING! magic library not found, go get it"
+ echo " from http://www.darwinsys.com/file/ or your distribution:"
+ echo
+ echo " Ubuntu: apt-get install libmagic-dev"
+ echo " Fedora: yum install file-devel"
+ echo
+ enable_magic="no"
+ fi
fi
# Napatech - Using the 3GD API
@@ -1995,6 +2008,7 @@
Unix socket enabled: ${enable_unixsocket}
Detection enabled: ${enable_detection}
+ Libmagic support: ${enable_magic}
libnss support: ${enable_nss}
libnspr support: ${enable_nspr}
libjansson support: ${enable_jansson}
diff -Nru suricata-3.2/debian/changelog suricata-3.2.1/debian/changelog
--- suricata-3.2/debian/changelog 2017-01-10 09:27:59.000000000 +0100
+++ suricata-3.2.1/debian/changelog 2017-02-20 13:29:37.000000000 +0100
@@ -1,3 +1,18 @@
+suricata (3.2.1-1~exp2) experimental; urgency=medium
+
+ [ Sascha Steinbiss ]
+ * [ced48e4] suricata: migrate from old split binary scheme (Closes: #855573)
+
+ -- Arturo Borrero Gonzalez <arturo@debian.org> Mon, 20 Feb 2017 13:29:37 +0100
+
+suricata (3.2.1-1~exp1) experimental; urgency=medium
+
+ * [67004c8] New upstream version 3.2.1
+ * [05b1756] d/control: bump dependency on libhyperscan
+ * [4483d1c] suricata: drop suricata-hyperscan binary package (Closes: #851647)
+
+ -- Arturo Borrero Gonzalez <arturo@debian.org> Wed, 15 Feb 2017 20:54:17 +0100
+
suricata (3.2-2) unstable; urgency=medium
* Rebuild for unstable.
diff -Nru suricata-3.2/debian/control suricata-3.2.1/debian/control
--- suricata-3.2/debian/control 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/control 2017-02-20 13:29:37.000000000 +0100
@@ -6,14 +6,13 @@
Build-Depends: autotools-dev,
debhelper (>= 9),
dh-autoreconf,
- dh-exec,
dh-systemd,
libcap-ng-dev,
libgeoip-dev,
libhiredis-dev,
libjansson-dev,
libluajit-5.1-dev [i386 amd64 powerpc mips armel armhf],
- libhyperscan-dev [i386 amd64 x32],
+ libhyperscan-dev (>= 4.4.0) [i386 amd64 x32],
libmagic-dev,
libnet1-dev | libnet-dev,
libnetfilter-log-dev,
@@ -37,8 +36,8 @@
Architecture: linux-any
Pre-Depends: dpkg (>= 1.15.7.2)
Depends: ${misc:Depends}, ${python:Depends}, ${shlibs:Depends}, libhtp-0.5.23-1 (= ${binary:Version}), lsb-base (>= 3.0-6)
-Conflicts: libhtp1 (<< 0.5.16)
-Replaces: libhtp1 (<< 0.5.16)
+Conflicts: libhtp1 (<< 0.5.16), suricata-hyperscan (<< 3.2)
+Replaces: libhtp1 (<< 0.5.16), suricata-hyperscan (<< 3.2)
Recommends: suricata-oinkmaster (=${binary:Version}), python, snort-rules-default
Suggests: libtcmalloc-minimal4
Description: Next Generation Intrusion Detection and Prevention Tool
@@ -56,17 +55,6 @@
.
This version has inline (NFQUEUE) support enabled.
-Package: suricata-hyperscan
-Architecture: linux-amd64 linux-i386 linux-x32
-Pre-Depends: dpkg (>= 1.15.7.2)
-Depends: ${misc:Depends}, ${shlibs:Depends}, suricata (=${binary:Version}), libhyperscan4
-Description: Next Generation Intrusion Detection and Prevention Tool, Hyperscan support
- Suricata is a network Intrusion Detection System (IDS). It is based on
- rules (and is fully compatible with snort rules) to detect a variety of
- attacks / probes by searching packet content.
- .
- This package adds Hyperscan support to an installed Suricata version.
-
Package: suricata-oinkmaster
Architecture: all
Depends: oinkmaster, suricata (>= ${source:Version}), ${misc:Depends}
diff -Nru suricata-3.2/debian/patches/optional-hyperscan.patch suricata-3.2.1/debian/patches/optional-hyperscan.patch
--- suricata-3.2/debian/patches/optional-hyperscan.patch 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/patches/optional-hyperscan.patch 1970-01-01 01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-Description: enable optional hyperscan support
- This patch allows one to disable and enable Hyperscan support independently of
- libhyperscan presence.
-Author: Sascha Steinbiss <satta@debian.org>
---- a/configure.ac
-+++ b/configure.ac
-@@ -595,8 +595,12 @@
- # libhs
- enable_hyperscan="no"
-
-- # Try pkg-config first:
-- PKG_CHECK_MODULES([libhs], libhs,, [with_pkgconfig_libhs=no])
-+ AC_ARG_ENABLE([libhs], AS_HELP_STRING([--enable-libhs], [try building with Hyperscan support]))
-+ if test "x$enable_libhs" = "xyes"; then
-+ # Try pkg-config first:
-+ PKG_CHECK_MODULES([libhs], libhs,, [with_pkgconfig_libhs=no])
-+ fi
-+
- if test "$with_pkgconfig_libhs" != "no"; then
- CPPFLAGS="${CPPFLAGS} ${libhs_CFLAGS}"
- LIBS="${LIBS} ${libhs_LIBS}"
diff -Nru suricata-3.2/debian/patches/series suricata-3.2.1/debian/patches/series
--- suricata-3.2/debian/patches/series 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/patches/series 2017-02-20 13:29:37.000000000 +0100
@@ -1,3 +1,2 @@
reproducible.patch
debian-default-cfg.patch
-optional-hyperscan.patch
diff -Nru suricata-3.2/debian/rules suricata-3.2.1/debian/rules
--- suricata-3.2/debian/rules 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/rules 2017-02-20 13:29:37.000000000 +0100
@@ -10,11 +10,9 @@
# Uncomment this to turn on verbose mode.
export DH_VERBOSE=1
+SURICATA_DESTDIR = $(CURDIR)/debian/suricata
export DEB_BUILD_MAINT_OPTIONS=hardening=+pie,+bindnow
-SURICATA_DESTDIR = $(CURDIR)/debian/build-tmp/suricata-no-hs
-SURICATA_HSDESTDIR = $(CURDIR)/debian/build-tmp/suricata-hs
-
ARCH ?= $(shell dpkg --print-architecture)
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
@@ -25,9 +23,8 @@
ENABLE_LUAJIT="--enable-luajit"
endif
-TARGETS = suricata-no-hs
ifneq (,$(findstring $(ARCH),$(HYPERSCAN_ARCHS)))
- TARGETS += suricata-with-hs
+ ENABLE_HYPERSCAN="--enable-libhs"
endif
CONFIGURE_ARGS = --enable-af-packet --enable-nfqueue --enable-prelude --enable-nflog \
@@ -36,41 +33,22 @@
--with-libnspr-includes=/usr/include/nspr --with-libnspr-libraries=/usr/lib/$(DEB_HOST_MULTIARCH) \
--disable-coccinelle \
--enable-geoip --enable-hiredis \
- $(ENABLE_LUAJIT)
+ $(ENABLE_LUAJIT) \
+ $(ENABLE_HYPERSCAN)
-suricata-no-hs:
+override_dh_auto_configure:
dh_auto_configure -- $(CONFIGURE_ARGS)
- dh_auto_build --parallel
- make install DESTDIR=$(SURICATA_DESTDIR)
+
+override_dh_auto_install:
+ dh_auto_install
rm -rf $(SURICATA_DESTDIR)/usr/lib/python*;\
(cd scripts/suricatasc &&\
python -B setup.py install --install-layout=deb --prefix $(SURICATA_DESTDIR)/usr)
# clean upstream install documentation
rm -rf $(SURICATA_DESTDIR)/usr/share/doc/suricata/*
- make clean
-
-suricata-with-hs:
- dh_auto_configure -- $(CONFIGURE_ARGS) --enable-libhs
- dh_auto_build --parallel
- make install DESTDIR=$(SURICATA_HSDESTDIR)
- rm -rf $(SURICATA_HSDESTDIR)/usr/lib/python*;\
- (cd scripts/suricatasc &&\
- python -B setup.py install --install-layout=deb --prefix $(SURICATA_HSDESTDIR)/usr)
- # clean upstream install documentation
- rm -rf $(SURICATA_HSDESTDIR)/usr/share/doc/suricata/*
- make clean
-
-override_dh_auto_clean:
- rm -rf $(CURDIR)/debian/build-tmp
- dh_auto_clean
-
-override_dh_auto_configure:
- # done in individual targets
-
-override_dh_auto_build: $(TARGETS)
override_dh_strip:
dh_strip --dbg-package=suricata-dbg
%:
- dh $@ --with autotools-dev,autoreconf,python2
+ dh $@ --parallel --with autotools-dev,autoreconf,python2
diff -Nru suricata-3.2/debian/suricata-hyperscan.install suricata-3.2.1/debian/suricata-hyperscan.install
--- suricata-3.2/debian/suricata-hyperscan.install 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/suricata-hyperscan.install 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-#!/usr/bin/dh-exec --with-scripts=install-rename
-
-debian/build-tmp/suricata-hs/usr/bin/suricata => /usr/bin/suricata.hyperscan
diff -Nru suricata-3.2/debian/suricata-hyperscan.postinst suricata-3.2.1/debian/suricata-hyperscan.postinst
--- suricata-3.2/debian/suricata-hyperscan.postinst 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/suricata-hyperscan.postinst 1970-01-01 01:00:00.000000000 +0100
@@ -1,8 +0,0 @@
-#!/bin/sh
-set -e
-
-update-alternatives --install /usr/bin/suricata suricata /usr/bin/suricata.hyperscan 110
-
-#DEBHELPER#
-
-exit 0
diff -Nru suricata-3.2/debian/suricata-hyperscan.prerm suricata-3.2.1/debian/suricata-hyperscan.prerm
--- suricata-3.2/debian/suricata-hyperscan.prerm 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/suricata-hyperscan.prerm 1970-01-01 01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-#!/bin/sh
-set -e
-
-case "$1" in
- # only remove in remove/deconfigure so we don't disrupt users' preferences
- remove|deconfigure)
- update-alternatives --remove suricata /usr/bin/suricata.hyperscan
- ;;
-
- upgrade|failed-upgrade)
- ;;
-
- *)
- echo "prerm called with unknown argument \`$1'" >&2
- exit 0
- ;;
-esac
-
-#DEBHELPER#
-
-exit 0
diff -Nru suricata-3.2/debian/suricata.init suricata-3.2.1/debian/suricata.init
--- suricata-3.2/debian/suricata.init 2016-12-01 16:17:43.000000000 +0100
+++ suricata-3.2.1/debian/suricata.init 2017-02-20 13:29:37.000000000 +0100
@@ -12,13 +12,14 @@
# match against a set of known attacks.
### END INIT INFO
+# Source function library.
. /lib/lsb/init-functions
-# Source function library.
if test -f /etc/default/suricata; then
. /etc/default/suricata
else
- echo "/etc/default/suricata is missing... bailing out!"
+ echo "/etc/default/suricata is missing... bailing out!" >&2
+ exit 1
fi
# We'll add up all the options above and use them
diff -Nru suricata-3.2/debian/suricata.install suricata-3.2.1/debian/suricata.install
--- suricata-3.2/debian/suricata.install 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/suricata.install 2017-02-20 13:29:37.000000000 +0100
@@ -1,10 +1,6 @@
-#!/usr/bin/dh-exec --with-scripts=install-rename
-
classification.config /etc/suricata
reference.config /etc/suricata
rules/*.rules /etc/suricata/rules
suricata.yaml /etc/suricata
threshold.config /etc/suricata
-debian/build-tmp/suricata-no-hs/usr/bin/suricata => /usr/bin/suricata.generic
-debian/build-tmp/suricata-no-hs/usr/bin/suricatasc usr/bin
-debian/build-tmp/suricata-no-hs/usr/lib/python* usr/lib
+usr/bin/*
diff -Nru suricata-3.2/debian/suricata.postinst suricata-3.2.1/debian/suricata.postinst
--- suricata-3.2/debian/suricata.postinst 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/suricata.postinst 1970-01-01 01:00:00.000000000 +0100
@@ -1,8 +0,0 @@
-#!/bin/sh
-set -e
-
-update-alternatives --install /usr/bin/suricata suricata /usr/bin/suricata.generic 100
-
-#DEBHELPER#
-
-exit 0
diff -Nru suricata-3.2/debian/suricata.preinst suricata-3.2.1/debian/suricata.preinst
--- suricata-3.2/debian/suricata.preinst 1970-01-01 01:00:00.000000000 +0100
+++ suricata-3.2.1/debian/suricata.preinst 2017-02-20 13:29:37.000000000 +0100
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# we do not need alternatives anymore
+if update-alternatives --quiet --query suricata 2> /dev/null; then
+ echo "Removing legacy alternatives for Hyperscan/non-Hyperscan versions"
+ update-alternatives --remove-all suricata
+fi
+
+#DEBHELPER#
+
+exit 0
diff -Nru suricata-3.2/debian/suricata.prerm suricata-3.2.1/debian/suricata.prerm
--- suricata-3.2/debian/suricata.prerm 2017-01-10 09:23:22.000000000 +0100
+++ suricata-3.2.1/debian/suricata.prerm 1970-01-01 01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-#!/bin/sh
-set -e
-
-case "$1" in
- # only remove in remove/deconfigure so we don't disrupt users' preferences
- remove|deconfigure)
- update-alternatives --remove suricata /usr/bin/suricata.generic
- ;;
-
- upgrade|failed-upgrade)
- ;;
-
- *)
- echo "prerm called with unknown argument \`$1'" >&2
- exit 0
- ;;
-esac
-
-#DEBHELPER#
-
-exit 0
diff -Nru suricata-3.2/doc/userguide/capture-hardware/index.rst suricata-3.2.1/doc/userguide/capture-hardware/index.rst
--- suricata-3.2/doc/userguide/capture-hardware/index.rst 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/doc/userguide/capture-hardware/index.rst 2017-02-15 08:54:12.000000000 +0100
@@ -4,4 +4,5 @@
.. toctree::
endace-dag
+ napatech
myricom
diff -Nru suricata-3.2/doc/userguide/capture-hardware/napatech.rst suricata-3.2.1/doc/userguide/capture-hardware/napatech.rst
--- suricata-3.2/doc/userguide/capture-hardware/napatech.rst 1970-01-01 01:00:00.000000000 +0100
+++ suricata-3.2.1/doc/userguide/capture-hardware/napatech.rst 2017-02-15 08:54:12.000000000 +0100
@@ -0,0 +1,215 @@
+
+
+Napatech Suricata Installation Guide
+=============================================================
+
+Contents
+--------
+
+ * Introduction
+
+ * Package Installation
+
+ * Basic Configuration
+
+ * Advanced Multithreaded Configuration
+
+Introduction
+------------
+
+Napatech packet capture accelerator cards can greatly improve the performance of your Suricata deployment using these
+hardware based features:
+
+ * On board burst buffering (up to 12GB)
+
+ * Zero-copy kernel bypass DMA
+
+ * Non-blocking PCIe performance
+
+ * Port merging
+
+ * Load distribution to up 128 host buffers
+
+ * Precise timestamping
+
+ * Accurate time synchronization
+
+The Napatech Software Suite (driver package) comes in two varieties, NAC and OEM.
+The NAC package distributes deb and rpm packages to ease the installation.
+The OEM package uses a proprietary shell script to handle the installation process.
+In either case, gcc, make and the kernel header files are required to compile the kernel module and
+install the software.
+
+
+Package Installation
+--------------------
+
+*Note that make, gcc, and the kernel headers are required for installation*
+
+*Root privileges are also required*
+
+Napatech NAC Package
+^^^^^^^^^^^^^^^^^^^^
+
+Red Hat Based Distros::
+
+ $ yum install kernel-devel-$(uname -r) gcc make ncurses-libs
+ $ yum install nac-pcap-<release>.x86_64.rpm
+
+Some distributions will require you to use the --nogpgcheck option with yum for the NAC Software Suite package file::
+
+ $ yum --nogpgcheck install nac-pcap-<release>.x86_64.rpm
+
+Debian Based Distros::
+
+ $ apt-get install linux-headers-$(uname .r) gcc make libncurses5
+ $ dpkg .i nac-pcap_<release>_amd64.deb
+
+To complete installation for all distros stop ntservice::
+
+ $ /opt/napatech3/bin/ntstop.sh -m
+
+Remove these existing setup files::
+
+ $ cd /opt/napatech3/config
+ $ rm ntservice.ini setup.ini
+
+Restart ntservice (a new ntservice.ini configuration file will be generated automatically)::
+
+ $ /opt/napatech3/bin/ntstart.sh -m
+
+
+Napatech OEM Package
+^^^^^^^^^^^^^^^^^^^^
+
+*Note that you will be prompted to install the Napatech libpcap library. Answer "yes" if you would like to
+use the Napatech card to capture packets in WIreshark, tcpdump, or another pcap based application.
+Libpcap is not needed for Suricata as native Napatech API support is included*
+
+Red Hat Based Distros::
+
+ $ yum install kernel-devel-$(uname -r) gcc make
+ $ ./package_install_3gd.sh
+
+Debian Based Distros::
+
+ $ apt-get install linux-headers-$(uname .r) gcc make
+ $ ./package_install_3gd.sh
+
+To complete installation for all distros ntservice::
+
+ $ /opt/napatech3/bin/ntstart.sh -m
+
+Suricata Installation
+---------------------
+
+After downloading and extracting the Suricata tarball, you need to run configure to enable Napatech support and
+prepare for compilation::
+
+ $ ./configure --enable_napatech --with-napatech-includes=/opt/napatech3/include --with-napatech-libraries=/opt/napatech3/lib
+ $ make
+ $ make install-full
+
+Now edit the suricata.yaml file to configure the maximum number of streams to use. If you plan on using the load distribution
+(RSS - like) feature in the Napatech accelerator, then the list should contain the same number of streams as host buffers defined in
+ntservice.ini::
+
+ Napatech:
+ # The Host Buffer Allowance for all streams
+ # (-1 = OFF, 1 - 100 = percentage of the host buffer that can be held back)
+ hba: -1
+
+ # use_all_streams set to "yes" will query the Napatech service for all configured
+ # streams and listen on all of them. When set to "no" the streams config array
+ # will be used.
+ use-all-streams: yes
+
+ # The streams to listen on
+ streams: [0, 1, 2, 3, 4, 5, 6, 7]
+
+
+Basic Configuration
+-------------------
+
+For the basic installation we will setup the Napatech capture accelerator to merge all physical
+ports into single stream that Suricata can read from. for this configuration, Suricata will
+handle the packet distribution to multiple threads.
+
+Here are the lines that need changing in /opt/napatech3/bin/ntservice.ini for best single buffer performance::
+
+ TimeSyncReferencePriority = OSTime # Timestamp clock synchronized to the OS
+ HostBuffersRx = [1,16,0] # [number of host buffers, Size(MB), NUMA node]
+
+Stop and restart ntservice after making changes to ntservice::
+
+ $ /opt/napatech3/bin/ntstop.sh -m
+ $ /opt/napatech3/bin/ntstart.sh -m
+
+Now we need to execute a few NTPL (Napatech Programming Language) commands to complete the setup. Create
+a file will the following commands::
+
+ Delete=All # Delete any existing filters
+ Setup[numaNode=0] = streamid==0 # Set stream ID 0 to NUMA 0
+ Assign[priority=0; streamid=0]= all # Assign all phisical ports to stream ID 0
+
+Next execute those command using the ntpl tool::
+
+ $ /opt/napatech3/bin/ntpl -f <my_ntpl_file>
+
+Now you are ready to start suricata::
+
+ $ suricata -c /usr/local/etc/suricata/suricata.yaml --napatech --runmode workers
+
+Advanced Multithreaded Configuration
+------------------------------------
+
+Now let's do a more advanced configuration where we will use the load distribution (RSS - like) capability in the
+accelerator. We will create 8 streams and setup the accelerator to distribute the load based on a 5 tuple hash.
+Increasing buffer size will minimize packet loss only if your CPU cores are fully saturated. Setting the minimum
+buffer size (16MB) will gave the best performance (minimize L3 cache hits) if your CPU cores are keeping up.
+
+*Note that it is extremely important that the NUMA node the host buffers are define in is the same physical CPU
+socket that the Napatech accelerator is plugged into*
+
+First let's modify the ntservice.ini file to increase the number and size of the host buffers::
+
+ HostBuffersRx = [8,256,0] # [number of host buffers, Size (MB), NUMA node]
+
+Stop and restart ntservice after making changes to ntservice::
+
+ $ /opt/napatech3/bin/ntstop.sh -m
+ $ /opt/napatech3/bin/ntstart.sh -m
+
+Now let's assign the streams to host buffers and configure the load distribution. The load distribution will be
+setup to support both tunneled and non-tunneled traffic. Create a file that contains the ntpl commands below::
+
+ Delete=All # Delete any existing filters
+ Setup[numaNode=0] = streamid==0
+ Setup[numaNode=0] = streamid==1
+ Setup[numaNode=0] = streamid==2
+ Setup[numaNode=0] = streamid==3
+ Setup[numaNode=0] = streamid==4
+ Setup[numaNode=0] = streamid==5
+ Setup[numaNode=0] = streamid==6
+ Setup[numaNode=0] = streamid==7
+ HashMode[priority=0; InnerLayer4Type=UDP, TCP, SCTP] = HashInner5TupleSorted
+ HashMode[priority=1; InnerLayer3Type=IPV4] = HashInner2TupleSorted
+ HashMode[priority=2; Layer4Type=UDP, TCP, SCTP] = Hash5TupleSorted
+ HashMode[priority=3; Layer3Type=IPV4] = Hash2TupleSorted
+ HashMode[priority=4]=HashRoundRobin
+ Assign[priority=0; streamid=(0..7)]= all
+
+Next execute those command using the ntpl tool::
+
+ $ /opt/napatech3/bin/ntpl -f <my_ntpl_file>
+
+Now you are ready to start Suricata::
+
+ $ suricata -c /usr/local/etc/suricata/suricata.yaml --napatech --runmode workers
+
+
+Support
+-------
+
+Contact a support engineer at: ntsupport@napatech.com
+
diff -Nru suricata-3.2/doc/userguide/output/lua-output.rst suricata-3.2.1/doc/userguide/output/lua-output.rst
--- suricata-3.2/doc/userguide/output/lua-output.rst 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/doc/userguide/output/lua-output.rst 2017-02-15 08:54:12.000000000 +0100
@@ -178,6 +178,22 @@
end
end
+SCFlowHasAlerts
+~~~~~~~~~~~~~~~
+
+Returns true if flow has alerts.
+
+Example:
+
+::
+
+ function log(args)
+ has_alerts = SCFlowHasAlerts()
+ if has_alerts then
+ -- do something
+ end
+ end
+
SCFlowStats
~~~~~~~~~~~
diff -Nru suricata-3.2/doc/userguide/rules/dnp3-keywords.rst suricata-3.2.1/doc/userguide/rules/dnp3-keywords.rst
--- suricata-3.2/doc/userguide/rules/dnp3-keywords.rst 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/doc/userguide/rules/dnp3-keywords.rst 2017-02-15 08:54:12.000000000 +0100
@@ -1,8 +1,6 @@
DNP3 Keywords
=============
-**NOTE: DNP3 is currently in development and is not yet available.**
-
The DNP3 keywords can be used to match on fields in decoded DNP3
messages. The keywords are based on Snort's DNP3 keywords and aim to
be 100% compatible.
diff -Nru suricata-3.2/doc/userguide/rules/index.rst suricata-3.2.1/doc/userguide/rules/index.rst
--- suricata-3.2/doc/userguide/rules/index.rst 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/doc/userguide/rules/index.rst 2017-02-15 08:54:12.000000000 +0100
@@ -11,6 +11,7 @@
http-keywords
flow-keywords
flowint
+ xbits
file-keywords
thresholding
dns-keywords
diff -Nru suricata-3.2/doc/userguide/rules/tls-keywords.rst suricata-3.2.1/doc/userguide/rules/tls-keywords.rst
--- suricata-3.2/doc/userguide/rules/tls-keywords.rst 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/doc/userguide/rules/tls-keywords.rst 2017-02-15 08:54:12.000000000 +0100
@@ -27,6 +27,18 @@
``tls_cert_issuer`` is a 'Sticky buffer'.
+tls_sni
+-------
+
+Match TLS/SSL Server Name Indication field.
+
+Examples::
+
+ tls_sni; content:"oisf.net"; nocase; isdataat:!1,relative;
+ tls_sni; content:"oisf.net"; nocase; pcre:"/oisf.net$/";
+
+``tls_sni`` is a 'Sticky buffer'.
+
tls_cert_notbefore
------------------
diff -Nru suricata-3.2/doc/userguide/rules/xbits.rst suricata-3.2.1/doc/userguide/rules/xbits.rst
--- suricata-3.2/doc/userguide/rules/xbits.rst 1970-01-01 01:00:00.000000000 +0100
+++ suricata-3.2.1/doc/userguide/rules/xbits.rst 2017-02-15 08:54:12.000000000 +0100
@@ -0,0 +1,48 @@
+Xbits
+=====
+
+Set, unset, toggle and check for bits stored per host or ip_pair.
+
+Syntax::
+
+ xbits:noalert;
+ xbits:<set|unset|isset|toggle>,<name>,track <ip_src|ip_dst|ip_pair>;
+ xbits:<set|unset|isset|toggle>,<name>,track <ip_src|ip_dst|ip_pair> \
+ [,expire <seconds>];
+ xbits:<set|unset|isset|toggle>,<name>,track <ip_src|ip_dst|ip_pair> \
+ [,expire <seconds>];
+
+YAML settings
+-------------
+
+Bits that are stored per host are stored in the Host table.
+
+Bits that are stored per IP pair are stored in the IPPair table.
+
+Threading
+---------
+
+Due to subtle timing issues between threads the order of sets and checks
+can be slightly unpredictible.
+
+Example: create a SSH blacklist
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Below is an example of rules incoming to a SSH server.
+
+The first 2 rules match on a SSH software version often used in bots.
+They drop the traffic and create an 'xbit' 'badssh' for the source ip.
+It expires in an hour::
+
+ drop ssh any any -> $MYSERVER 22 (msg:"DROP libssh incoming"; \
+ flow:to_server,established; ssh.softwareversion:"libssh"; \
+ xbits:set, badssh, track ip_src, expire 3600; sid:4000000005;)
+ drop ssh any any -> $MYSERVER 22 (msg:"DROP PUTTY incoming"; \
+ flow:to_server,established; ssh.softwareversion:"PUTTY"; \
+ xbits:set, badssh, track ip_src, expire 3600; sid:4000000007;)
+
+Then the following rule simply drops any incoming traffic to that server
+that is on that 'badssh' list::
+
+ drop ssh any any -> $MYSERVER 22 (msg:"DROP BLACKLISTED"; \
+ xbits:isset, badssh, track ip_src; sid:4000000006;)
diff -Nru suricata-3.2/doc/userguide/suricata.1 suricata-3.2.1/doc/userguide/suricata.1
--- suricata-3.2/doc/userguide/suricata.1 2016-11-29 18:17:15.000000000 +0100
+++ suricata-3.2.1/doc/userguide/suricata.1 2017-02-15 08:54:46.000000000 +0100
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH "SURICATA" "1" "November 29, 2016" "3.2" "Suricata"
+.TH "SURICATA" "1" "February 15, 2017" "3.2.1" "Suricata"
.SH NAME
suricata \- Suricata
.
Los ficheros binarios /tmp/5ANamyhz3M/suricata-3.2/doc/userguide/userguide.pdf y /tmp/OrowFu7tes/suricata-3.2.1/doc/userguide/userguide.pdf son distintos
diff -Nru suricata-3.2/rules/tls-events.rules suricata-3.2.1/rules/tls-events.rules
--- suricata-3.2/rules/tls-events.rules 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/rules/tls-events.rules 2017-02-15 08:54:12.000000000 +0100
@@ -26,5 +26,6 @@
alert tls any any -> any any (msg:"SURICATA TLS invalid SNI type"; flow:established,to_server; app-layer-event:tls.invalid_sni_type; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230017; rev:1;)
alert tls any any -> any any (msg:"SURICATA TLS invalid SNI length"; flow:established,to_server; app-layer-event:tls.invalid_sni_length; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230018; rev:1;)
alert tls any any -> any any (msg:"SURICATA TLS handshake invalid length"; flow:established; app-layer-event:tls.handshake_invalid_length; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230019; rev:1;)
+alert tls any any -> any any (msg:"SURICATA TLS too many records in packet"; flow:established; app-layer-event:tls.too_many_records_in_packet; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230020; rev:1;)
-#next sid is 2230020
+#next sid is 2230021
diff -Nru suricata-3.2/scripts/suricatasc/Makefile.in suricata-3.2.1/scripts/suricatasc/Makefile.in
--- suricata-3.2/scripts/suricatasc/Makefile.in 2016-11-29 18:17:05.000000000 +0100
+++ suricata-3.2.1/scripts/suricatasc/Makefile.in 2017-02-15 08:54:31.000000000 +0100
@@ -423,8 +423,8 @@
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-@HAVE_PYTHON_FALSE@uninstall-local:
@HAVE_PYTHON_FALSE@clean-local:
+@HAVE_PYTHON_FALSE@uninstall-local:
@HAVE_PYTHON_FALSE@install-exec-local:
clean: clean-am
diff -Nru suricata-3.2/src/alert-prelude.c suricata-3.2.1/src/alert-prelude.c
--- suricata-3.2/src/alert-prelude.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/alert-prelude.c 2017-02-15 08:54:12.000000000 +0100
@@ -512,10 +512,10 @@
AddIntData(alert, "tcp_win", TCP_GET_WINDOW(p));
AddIntData(alert, "tcp_sum", TCP_GET_SUM(p));
AddIntData(alert, "tcp_urp", TCP_GET_URG_POINTER(p));
- if (p->tcpvars.ts_val != NULL) {
+ if (p->tcpvars.ts_val != 0) {
AddIntData(alert, "tcp_tsval", TCP_GET_TSVAL(p));
}
- if (p->tcpvars.ts_ecr != NULL) {
+ if (p->tcpvars.ts_ecr != 0) {
AddIntData(alert, "tcp_tsecr", TCP_GET_TSECR(p));
}
if (p->tcph != NULL) {
@@ -961,4 +961,3 @@
AlertPreludeThreadInit, AlertPreludeThreadDeinit, NULL);
}
#endif /* PRELUDE */
-
diff -Nru suricata-3.2/src/app-layer-dcerpc.c suricata-3.2.1/src/app-layer-dcerpc.c
--- suricata-3.2/src/app-layer-dcerpc.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-dcerpc.c 2017-02-15 08:54:12.000000000 +0100
@@ -1553,7 +1553,9 @@
(dcerpc->dcerpchdr.type == BIND) ?
"BIND" : "ALTER_CONTEXT");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1579,7 +1581,9 @@
//parsed -= input_len;
SCLogDebug("Error Parsing CTX Item %u\n", parsed);
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
dcerpc->dcerpcbindbindack.numctxitemsleft = 0;
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
@@ -1606,7 +1610,9 @@
} else {
SCLogDebug("Error Parsing DCERPC");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1633,7 +1639,9 @@
(dcerpc->dcerpchdr.type == BIND_ACK) ?
"BIND_ACK" : "ALTER_CONTEXT_RESP");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1652,7 +1660,9 @@
} else if (input_len) {
SCLogDebug("Error parsing Secondary Address");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1679,7 +1689,9 @@
} else if (input_len) {
SCLogDebug("Error parsing DCERPC Padding");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1698,7 +1710,9 @@
} else if (input_len) {
SCLogDebug("Error parsing CTX Items");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1721,7 +1735,9 @@
} else if (input_len) {
SCLogDebug("Error parsing CTX Items");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
dcerpc->dcerpcbindbindack.numctxitemsleft = 0;
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
@@ -1759,7 +1775,9 @@
} else {
SCLogDebug("Error Parsing DCERPC");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1783,8 +1801,10 @@
SCLogDebug("Error parsing DCERPC %s",
(dcerpc->dcerpchdr.type == REQUEST) ? "REQUEST" : "RESPONSE");
parsed = 0;
+ (void)parsed; /* for scan-build */
dcerpc->padleft = 0;
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1800,7 +1820,9 @@
} else if (input_len) {
SCLogDebug("Error parsing DCERPC Stub Data");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1842,7 +1864,9 @@
} else {
SCLogDebug("Error Parsing DCERPC");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
@@ -1875,7 +1899,9 @@
} else {
SCLogDebug("Error Parsing DCERPC");
parsed = 0;
+ (void)parsed; /* for scan-build */
input_len = 0;
+ (void)input_len; /* for scan-build */
DCERPCResetParsingState(dcerpc);
SCReturnInt(0);
}
diff -Nru suricata-3.2/src/app-layer-detect-proto.c suricata-3.2.1/src/app-layer-detect-proto.c
--- suricata-3.2/src/app-layer-detect-proto.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-detect-proto.c 2017-02-15 08:54:12.000000000 +0100
@@ -75,8 +75,12 @@
uint32_t min_depth;
/* the max length of data after which this parser won't be invoked */
uint32_t max_depth;
- /* the probing parser function */
- ProbingParserFPtr ProbingParser;
+
+ /* the to_server probing parser function */
+ ProbingParserFPtr ProbingParserTs;
+
+ /* the to_client probing parser function */
+ ProbingParserFPtr ProbingParserTc;
struct AppLayerProtoDetectProbingParserElement_ *next;
} AppLayerProtoDetectProbingParserElement;
@@ -395,7 +399,11 @@
continue;
}
- alproto = pe->ProbingParser(buf, buflen, NULL);
+ if (direction & STREAM_TOSERVER && pe->ProbingParserTs != NULL) {
+ alproto = pe->ProbingParserTs(buf, buflen, NULL);
+ } else if (pe->ProbingParserTc != NULL) {
+ alproto = pe->ProbingParserTc(buf, buflen, NULL);
+ }
if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED)
goto end;
if (alproto == ALPROTO_FAILED ||
@@ -412,7 +420,11 @@
continue;
}
- alproto = pe->ProbingParser(buf, buflen, NULL);
+ if (direction & STREAM_TOSERVER && pe->ProbingParserTs != NULL) {
+ alproto = pe->ProbingParserTs(buf, buflen, NULL);
+ } else if (pe->ProbingParserTc != NULL) {
+ alproto = pe->ProbingParserTc(buf, buflen, NULL);
+ }
if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED)
goto end;
if (alproto == ALPROTO_FAILED ||
@@ -429,8 +441,6 @@
mask = pp_port_dp->alproto_mask;
else if (pp_port_sp)
mask = pp_port_sp->alproto_mask;
- else
- mask = 0;
if (alproto_masks[0] == mask) {
FLOW_SET_PP_DONE(f, direction);
@@ -579,9 +589,7 @@
AppLayerProtoDetectProbingParserElementCreate(AppProto alproto,
uint16_t port,
uint16_t min_depth,
- uint16_t max_depth,
- uint16_t (*AppLayerProtoDetectProbingParserFunc)
- (uint8_t *input, uint32_t input_len, uint32_t *offset))
+ uint16_t max_depth)
{
AppLayerProtoDetectProbingParserElement *pe = AppLayerProtoDetectProbingParserElementAlloc();
@@ -590,7 +598,6 @@
pe->alproto_mask = AppLayerProtoDetectProbingParserGetMask(alproto);
pe->min_depth = min_depth;
pe->max_depth = max_depth;
- pe->ProbingParser = AppLayerProtoDetectProbingParserFunc;
pe->next = NULL;
if (max_depth != 0 && min_depth >= max_depth) {
@@ -603,11 +610,6 @@
"the probing parser. Invalid alproto - %d", alproto);
goto error;
}
- if (AppLayerProtoDetectProbingParserFunc == NULL) {
- SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to "
- "register the probing parser. Probing parser func NULL");
- goto error;
- }
SCReturnPtr(pe, "AppLayerProtoDetectProbingParserElement");
error:
@@ -627,7 +629,8 @@
new_pe->alproto_mask = pe->alproto_mask;
new_pe->min_depth = pe->min_depth;
new_pe->max_depth = pe->max_depth;
- new_pe->ProbingParser = pe->ProbingParser;
+ new_pe->ProbingParserTs = pe->ProbingParserTs;
+ new_pe->ProbingParserTc = pe->ProbingParserTc;
new_pe->next = NULL;
SCReturnPtr(new_pe, "AppLayerProtoDetectProbingParserElement");
@@ -860,7 +863,8 @@
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
uint8_t direction,
- ProbingParserFPtr ProbingParser)
+ ProbingParserFPtr ProbingParser1,
+ ProbingParserFPtr ProbingParser2)
{
SCEnter();
@@ -964,13 +968,14 @@
AppLayerProtoDetectProbingParserElement *new_pe =
AppLayerProtoDetectProbingParserElementCreate(alproto,
curr_port->port,
- min_depth, max_depth,
- ProbingParser);
+ min_depth, max_depth);
if (new_pe == NULL)
goto error;
curr_pe = new_pe;
AppLayerProtoDetectProbingParserElement **head_pe;
if (direction & STREAM_TOSERVER) {
+ curr_pe->ProbingParserTs = ProbingParser1;
+ curr_pe->ProbingParserTc = ProbingParser2;
if (curr_port->dp == NULL)
curr_port->dp_max_depth = new_pe->max_depth;
if (new_pe->max_depth == 0)
@@ -982,6 +987,8 @@
curr_port->alproto_mask |= new_pe->alproto_mask;
head_pe = &curr_port->dp;
} else {
+ curr_pe->ProbingParserTs = ProbingParser2;
+ curr_pe->ProbingParserTc = ProbingParser1;
if (curr_port->sp == NULL)
curr_port->sp_max_depth = new_pe->max_depth;
if (new_pe->max_depth == 0)
@@ -1390,7 +1397,8 @@
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
uint8_t direction,
- ProbingParserFPtr ProbingParser)
+ ProbingParserFPtr ProbingParser1,
+ ProbingParserFPtr ProbingParser2)
{
SCEnter();
@@ -1408,7 +1416,8 @@
alproto,
min_depth, max_depth,
direction,
- ProbingParser);
+ ProbingParser1,
+ ProbingParser2);
}
temp_dp = temp_dp->next;
}
@@ -1422,7 +1431,8 @@
const char *alproto_name,
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
- ProbingParserFPtr ProbingParser)
+ ProbingParserFPtr ProbingParserTs,
+ ProbingParserFPtr ProbingParserTc)
{
SCEnter();
@@ -1469,7 +1479,7 @@
alproto,
min_depth, max_depth,
STREAM_TOSERVER, /* to indicate dp */
- ProbingParser);
+ ProbingParserTs, ProbingParserTc);
}
/* detect by source port of flow */
@@ -1483,7 +1493,7 @@
alproto,
min_depth, max_depth,
STREAM_TOCLIENT, /* to indicate sp */
- ProbingParser);
+ ProbingParserTc, ProbingParserTs);
}
@@ -1540,7 +1550,7 @@
#ifdef __SC_CUDA_SUPPORT__
/* CUDA won't work here, so fall back to AC */
if (mpm_matcher == MPM_AC_CUDA)
- mpm_matcher = DEFAULT_MPM;
+ mpm_matcher = mpm_default_matcher;
#endif
alpd_ctx.spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
@@ -1614,6 +1624,9 @@
ConfNode *node;
int r;
+#ifdef AFLFUZZ_APPLAYER
+ goto enabled;
+#endif
if (RunmodeIsUnittests())
goto enabled;
@@ -2980,57 +2993,57 @@
ALPROTO_HTTP,
5, 8,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_SMB,
5, 6,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_FTP,
7, 10,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_DCERPC,
9, 10,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_FTP,
7, 15,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_SMTP,
12, 0,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_TLS,
12, 18,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"85",
ALPROTO_DCERPC,
9, 10,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"85",
ALPROTO_FTP,
7, 15,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
result = 1;
AppLayerProtoDetectPPRegister(IPPROTO_UDP,
@@ -3038,7 +3051,7 @@
ALPROTO_IMAP,
12, 23,
STREAM_TOSERVER,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
/* toclient */
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
@@ -3046,74 +3059,74 @@
ALPROTO_JABBER,
12, 23,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_IRC,
12, 14,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"85",
ALPROTO_DCERPC,
9, 10,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_FTP,
7, 15,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_TLS,
12, 18,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_HTTP,
5, 8,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_DCERPC,
9, 10,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"90",
ALPROTO_FTP,
7, 15,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_SMB,
5, 6,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_UDP,
"85",
ALPROTO_IMAP,
12, 23,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_SMTP,
12, 17,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_FTP,
7, 10,
STREAM_TOCLIENT,
- ProbingParserDummyForTesting);
+ ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPTestDataElement element_ts_80[] = {
{ "http", ALPROTO_HTTP, 80, 1 << ALPROTO_HTTP, 5, 8 },
diff -Nru suricata-3.2/src/app-layer-detect-proto.h suricata-3.2.1/src/app-layer-detect-proto.h
--- suricata-3.2/src/app-layer-detect-proto.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-detect-proto.h 2017-02-15 08:54:12.000000000 +0100
@@ -65,7 +65,8 @@
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
uint8_t direction,
- ProbingParserFPtr ProbingParser);
+ ProbingParserFPtr ProbingParser1,
+ ProbingParserFPtr ProbingParser2);
/**
* \retval bool 0 if no config was found, 1 if config was found
*/
@@ -74,7 +75,8 @@
const char *alproto_name,
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
- ProbingParserFPtr ProbingParser);
+ ProbingParserFPtr ProbingParserTs,
+ ProbingParserFPtr ProbingParserTc);
/***** PM registration *****/
diff -Nru suricata-3.2/src/app-layer-dnp3.c suricata-3.2.1/src/app-layer-dnp3.c
--- suricata-3.2/src/app-layer-dnp3.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-dnp3.c 2017-02-15 08:54:12.000000000 +0100
@@ -1592,13 +1592,15 @@
if (RunmodeIsUnittests()) {
AppLayerProtoDetectPPRegister(IPPROTO_TCP, DNP3_DEFAULT_PORT,
ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader), STREAM_TOSERVER,
- DNP3ProbingParser);
+ DNP3ProbingParser, NULL);
}
else {
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader),
- DNP3ProbingParser)) {
+ DNP3ProbingParser, NULL)) {
+#ifndef AFLFUZZ_APPLAYER
return;
+#endif
}
}
diff -Nru suricata-3.2/src/app-layer-dns-common.c suricata-3.2.1/src/app-layer-dns-common.c
--- suricata-3.2/src/app-layer-dns-common.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-dns-common.c 2017-02-15 08:54:12.000000000 +0100
@@ -605,6 +605,7 @@
return;
TAILQ_INSERT_TAIL(&dns_state->tx_list, tx, next);
dns_state->curr = tx;
+ dns_state->transaction_max++;
tx->tx_num = dns_state->transaction_max;
}
@@ -857,7 +858,7 @@
DNSStoreAnswerInState(dns_state, list, fqdn, fqdn_len,
ntohs(head->type), ntohs(head->class), ntohl(head->ttl),
- data, 4, ntohs(dns_header->tx_id));
+ data, datalen, ntohs(dns_header->tx_id));
} else {
SCLogDebug("invalid length for A response data: %u", ntohs(head->len));
goto bad_data;
@@ -875,7 +876,7 @@
DNSStoreAnswerInState(dns_state, list, fqdn, fqdn_len,
ntohs(head->type), ntohs(head->class), ntohl(head->ttl),
- data, 16, ntohs(dns_header->tx_id));
+ data, datalen, ntohs(dns_header->tx_id));
} else {
SCLogDebug("invalid length for AAAA response data: %u", ntohs(head->len));
goto bad_data;
diff -Nru suricata-3.2/src/app-layer-dns-tcp.c suricata-3.2.1/src/app-layer-dns-tcp.c
--- suricata-3.2/src/app-layer-dns-tcp.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-dns-tcp.c 2017-02-15 08:54:12.000000000 +0100
@@ -363,7 +363,7 @@
goto bad_data;
}
- if (dns_state != NULL && f != NULL) {
+ if (f != NULL) {
dns_state->last_req = f->lastts;
}
@@ -582,7 +582,7 @@
goto bad_data;
}
- if (dns_state != NULL && f != NULL) {
+ if (f != NULL) {
dns_state->last_req = f->lastts;
}
@@ -627,6 +627,28 @@
return ALPROTO_DNS;
}
+/**
+ * \brief Probing parser for TCP DNS responses.
+ *
+ * This is a minimal parser that just checks that the input contains enough
+ * data for a TCP DNS response.
+ */
+static uint16_t DNSTcpProbeResponse(uint8_t *input, uint32_t len,
+ uint32_t *offset)
+{
+ if (len == 0 || len < sizeof(DNSTcpHeader)) {
+ return ALPROTO_UNKNOWN;
+ }
+
+ DNSTcpHeader *dns_header = (DNSTcpHeader *)input;
+
+ if (ntohs(dns_header->len) < sizeof(DNSHeader)) {
+ return ALPROTO_FAILED;
+ }
+
+ return ALPROTO_DNS;
+}
+
void RegisterDNSTCPParsers(void)
{
char *proto_name = "dns";
@@ -641,12 +663,13 @@
ALPROTO_DNS,
0, sizeof(DNSTcpHeader),
STREAM_TOSERVER,
- DNSTcpProbingParser);
+ DNSTcpProbingParser, NULL);
} else {
int have_cfg = AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_DNS,
0, sizeof(DNSTcpHeader),
- DNSTcpProbingParser);
+ DNSTcpProbingParser,
+ DNSTcpProbeResponse);
/* if we have no config, we enable the default port 53 */
if (!have_cfg) {
SCLogWarning(SC_ERR_DNS_CONFIG, "no DNS TCP config found, "
@@ -654,7 +677,8 @@
"port 53.");
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "53",
ALPROTO_DNS, 0, sizeof(DNSTcpHeader),
- STREAM_TOSERVER, DNSTcpProbingParser);
+ STREAM_TOSERVER, DNSTcpProbingParser,
+ DNSTcpProbeResponse);
}
}
} else {
diff -Nru suricata-3.2/src/app-layer-dns-udp.c suricata-3.2.1/src/app-layer-dns-udp.c
--- suricata-3.2/src/app-layer-dns-udp.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-dns-udp.c 2017-02-15 08:54:12.000000000 +0100
@@ -314,7 +314,7 @@
tx->replied = 1;
}
- if (dns_state != NULL && f != NULL) {
+ if (f != NULL) {
dns_state->last_resp = f->lastts;
}
SCReturnInt(1);
@@ -395,20 +395,23 @@
ALPROTO_DNS,
0, sizeof(DNSHeader),
STREAM_TOSERVER,
- DNSUdpProbingParser);
+ DNSUdpProbingParser,
+ NULL);
} else {
int have_cfg = AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
proto_name, ALPROTO_DNS,
0, sizeof(DNSHeader),
- DNSUdpProbingParser);
+ DNSUdpProbingParser, NULL);
/* if we have no config, we enable the default port 53 */
if (!have_cfg) {
+#ifndef AFLFUZZ_APPLAYER
SCLogWarning(SC_ERR_DNS_CONFIG, "no DNS UDP config found, "
"enabling DNS detection on "
"port 53.");
+#endif
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "53",
ALPROTO_DNS, 0, sizeof(DNSHeader),
- STREAM_TOSERVER, DNSUdpProbingParser);
+ STREAM_TOSERVER, DNSUdpProbingParser, NULL);
}
}
} else {
diff -Nru suricata-3.2/src/app-layer-enip.c suricata-3.2.1/src/app-layer-enip.c
--- suricata-3.2/src/app-layer-enip.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-enip.c 2017-02-15 08:54:12.000000000 +0100
@@ -383,27 +383,27 @@
if (RunmodeIsUnittests())
{
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
- 0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser);
+ 0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
- 0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser);
+ 0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
} else
{
if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
- ENIPProbingParser))
+ ENIPProbingParser, ENIPProbingParser))
{
SCLogDebug(
"no ENIP UDP config found enabling ENIP detection on port 44818.");
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr), STREAM_TOSERVER,
- ENIPProbingParser);
+ ENIPProbingParser, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT,
- ENIPProbingParser);
+ ENIPProbingParser, NULL);
}
}
@@ -471,18 +471,20 @@
if (RunmodeIsUnittests())
{
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
- 0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser);
+ 0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
- 0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser);
+ 0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
} else
{
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
- ENIPProbingParser))
+ ENIPProbingParser, ENIPProbingParser))
{
+#ifndef AFLFUZZ_APPLAYER
return;
+#endif
}
}
diff -Nru suricata-3.2/src/app-layer-htp.c suricata-3.2.1/src/app-layer-htp.c
--- suricata-3.2/src/app-layer-htp.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-htp.c 2017-02-15 08:54:12.000000000 +0100
@@ -2737,7 +2737,7 @@
* 3 is subtracted from the length since the spacing is hex typed as |xx|
* but the pattern matching should only be one char
*/
- register_result = AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP,
+ register_result = AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP,
ALPROTO_HTTP, method_buffer, strlen(method_buffer)-3, 0, STREAM_TOSERVER);
if (register_result < 0) {
return -1;
@@ -2747,7 +2747,7 @@
/* Loop through all the http verions patterns that are TO_CLIENT */
for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
- register_result = AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP,
+ register_result = AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP,
ALPROTO_HTTP, versions[versions_pos], strlen(versions[versions_pos]),
0, STREAM_TOCLIENT);
if (register_result < 0) {
diff -Nru suricata-3.2/src/app-layer-htp-file.c suricata-3.2.1/src/app-layer-htp-file.c
--- suricata-3.2/src/app-layer-htp-file.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-htp-file.c 2017-02-15 08:54:12.000000000 +0100
@@ -633,11 +633,11 @@
}
if (http_state->files_ts->head == NULL ||
- FileSize(http_state->files_ts->head) != 11)
+ FileDataSize(http_state->files_ts->head) != 11)
{
if (http_state->files_ts->head != NULL)
printf("filedata len not 11 but %"PRIu64": ",
- FileSize(http_state->files_ts->head));
+ FileDataSize(http_state->files_ts->head));
goto end;
}
diff -Nru suricata-3.2/src/app-layer-modbus.c suricata-3.2.1/src/app-layer-modbus.c
--- suricata-3.2/src/app-layer-modbus.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-modbus.c 2017-02-15 08:54:12.000000000 +0100
@@ -1455,14 +1455,14 @@
ALPROTO_MODBUS,
0, sizeof(ModbusHeader),
STREAM_TOSERVER,
- ModbusProbingParser);
+ ModbusProbingParser, NULL);
} else {
/* If there is no app-layer section for Modbus, silently
* leave it disabled. */
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_MODBUS,
0, sizeof(ModbusHeader),
- ModbusProbingParser)) {
+ ModbusProbingParser, NULL)) {
#ifndef AFLFUZZ_APPLAYER
return;
#endif
@@ -1497,11 +1497,7 @@
return;
#endif
}
-#ifndef AFLFUZZ_APPLAYER
if (AppLayerParserConfParserEnabled("tcp", proto_name)) {
-#else
- if (1) {
-#endif
AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_MODBUS, STREAM_TOSERVER, ModbusParseRequest);
AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_MODBUS, STREAM_TOCLIENT, ModbusParseResponse);
AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_MODBUS, ModbusStateAlloc, ModbusStateFree);
diff -Nru suricata-3.2/src/app-layer-parser.c suricata-3.2.1/src/app-layer-parser.c
--- suricata-3.2/src/app-layer-parser.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-parser.c 2017-02-15 08:54:12.000000000 +0100
@@ -265,6 +265,10 @@
SCReturn;
}
+/** \brief check if a parser is enabled in the config
+ * Returns enabled always if: were running unittests and
+ * when compiled with --enable-afl
+ */
int AppLayerParserConfParserEnabled(const char *ipproto,
const char *alproto_name)
{
@@ -275,6 +279,9 @@
ConfNode *node;
int r;
+#ifdef AFLFUZZ_APPLAYER
+ goto enabled;
+#endif
if (RunmodeIsUnittests())
goto enabled;
@@ -597,12 +604,12 @@
SCReturnCT((pstate == NULL) ? 0 : pstate->log_id, "uint64_t");
}
-void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate)
+void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id)
{
SCEnter();
if (pstate != NULL)
- pstate->log_id++;
+ pstate->log_id = tx_id;
SCReturn;
}
@@ -1307,7 +1314,7 @@
#endif
#ifdef AFLFUZZ_APPLAYER
-int AppLayerParserRequestFromFile(AppProto alproto, char *filename)
+int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filename)
{
int result = 1;
Flow *f = NULL;
@@ -1327,7 +1334,8 @@
f->sp = 10000;
f->dp = 80;
f->protoctx = &ssn;
- f->proto = IPPROTO_TCP;
+ f->proto = ipproto;
+ f->protomap = FlowGetProtoMapping(f->proto);
f->alproto = alproto;
uint8_t buffer[64];
@@ -1344,8 +1352,8 @@
int start = 1;
while (1) {
int done = 0;
- size_t result = fread(&buffer, 1, sizeof(buffer), fp);
- if (result < sizeof(buffer))
+ size_t size = fread(&buffer, 1, sizeof(buffer), fp);
+ if (size < sizeof(buffer))
done = 1;
//SCLogInfo("result %u done %d start %d", (uint)result, done, start);
@@ -1361,7 +1369,7 @@
//PrintRawDataFp(stdout, buffer, result);
(void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
- buffer, result);
+ buffer, size);
if (done)
break;
}
@@ -1383,7 +1391,7 @@
return result;
}
-int AppLayerParserFromFile(AppProto alproto, char *filename)
+int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename)
{
int result = 1;
Flow *f = NULL;
@@ -1403,7 +1411,8 @@
f->sp = 10000;
f->dp = 80;
f->protoctx = &ssn;
- f->proto = IPPROTO_TCP;
+ f->proto = ipproto;
+ f->protomap = FlowGetProtoMapping(f->proto);
f->alproto = alproto;
uint8_t buffer[64];
@@ -1421,8 +1430,8 @@
int flip = 0;
while (1) {
int done = 0;
- size_t result = fread(&buffer, 1, sizeof(buffer), fp);
- if (result < sizeof(buffer))
+ size_t size = fread(&buffer, 1, sizeof(buffer), fp);
+ if (size < sizeof(buffer))
done = 1;
//SCLogInfo("result %u done %d start %d", (uint)result, done, start);
@@ -1445,7 +1454,7 @@
//PrintRawDataFp(stdout, buffer, result);
(void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
- buffer, result);
+ buffer, size);
if (done)
break;
}
diff -Nru suricata-3.2/src/app-layer-parser.h suricata-3.2.1/src/app-layer-parser.h
--- suricata-3.2/src/app-layer-parser.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-parser.h 2017-02-15 08:54:12.000000000 +0100
@@ -162,7 +162,7 @@
uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate);
-void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate);
+void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id);
void AppLayerParserSetTxLogged(uint8_t ipproto, AppProto alproto, void *alstate,
void *tx, uint32_t logger);
int AppLayerParserGetTxLogged(uint8_t ipproto, AppProto alproto, void *alstate,
@@ -237,8 +237,8 @@
#endif
#ifdef AFLFUZZ_APPLAYER
-int AppLayerParserRequestFromFile(AppProto alproto, char *filename);
-int AppLayerParserFromFile(AppProto alproto, char *filename);
+int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filename);
+int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename);
#endif
/***** Unittests *****/
diff -Nru suricata-3.2/src/app-layer-smb.c suricata-3.2.1/src/app-layer-smb.c
--- suricata-3.2/src/app-layer-smb.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-smb.c 2017-02-15 08:54:12.000000000 +0100
@@ -678,6 +678,7 @@
sstate->bytesprocessed += parsed;
sstate->bytecount.bytecountleft -= parsed;
input_len -= parsed;
+ (void)input_len; /* for scan-build */
}
}
SCReturnInt(parsed);
@@ -833,7 +834,9 @@
sres = DataParser(sstate, pstate, input + parsed, input_len);
if (sres != -1 && sres <= (int32_t)input_len) {
parsed += (uint32_t)sres;
+ (void)parsed; /* for scan-build */
input_len -= (uint32_t)sres;
+ (void)input_len; /* for scan-build */
} else { /* Did not Validate as DCERPC over SMB */
while (sstate->bytecount.bytecountleft-- && input_len--) {
SCLogDebug("0x%02x bytecount %"PRIu16"/%"PRIu16" input_len %"PRIu32, *p,
@@ -1497,18 +1500,17 @@
static int SMBRegisterPatternsForProtocolDetection(void)
{
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB,
- "|ff|SMB", 8, 4, STREAM_TOSERVER) < 0)
- {
- return -1;
- }
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2,
- "|fe|SMB", 8, 4, STREAM_TOSERVER) < 0)
- {
- return -1;
- }
-
- return 0;
+ int r = 0;
+ r |= AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB,
+ "|ff|SMB", 8, 4, STREAM_TOSERVER);
+ r |= AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB,
+ "|ff|SMB", 8, 4, STREAM_TOCLIENT);
+
+ r |= AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2,
+ "|fe|SMB", 8, 4, STREAM_TOSERVER);
+ r |= AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2,
+ "|fe|SMB", 8, 4, STREAM_TOCLIENT);
+ return r == 0 ? 0 : -1;
}
void RegisterSMBParsers(void)
@@ -1526,12 +1528,12 @@
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
- SMBProbingParser);
+ SMBProbingParser, SMBProbingParser);
} else {
AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
- SMBProbingParser);
+ SMBProbingParser, SMBProbingParser);
}
AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_SMB, STREAM_TOSERVER);
@@ -2217,7 +2219,7 @@
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
- SMBProbingParser);
+ SMBProbingParser, NULL);
AppLayerProtoDetectPrepareState();
alpd_tctx = AppLayerProtoDetectGetCtxThread();
@@ -2301,7 +2303,7 @@
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
- SMBProbingParser);
+ SMBProbingParser, NULL);
AppLayerProtoDetectPrepareState();
alpd_tctx = AppLayerProtoDetectGetCtxThread();
diff -Nru suricata-3.2/src/app-layer-smtp.c suricata-3.2.1/src/app-layer-smtp.c
--- suricata-3.2/src/app-layer-smtp.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-smtp.c 2017-02-15 08:54:12.000000000 +0100
@@ -157,7 +157,7 @@
PrefilterRuleStore *pmq;
} SMTPThreadCtx;
-#define SMTP_MPM DEFAULT_MPM
+#define SMTP_MPM mpm_default_matcher
static MpmCtx *smtp_mpm_ctx = NULL;
@@ -371,7 +371,7 @@
if (file->sb->stream_offset == 0)
window = MAX(window, smtp_config.content_inspect_min_size);
- uint64_t file_size = FileSize(file);
+ uint64_t file_size = FileDataSize(file);
uint64_t data_size = file_size - file->sb->stream_offset;
SCLogDebug("window %"PRIu32", file_size %"PRIu64", data_size %"PRIu64,
@@ -1490,17 +1490,17 @@
static int SMTPRegisterPatternsForProtocolDetection(void)
{
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMTP,
+ if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_SMTP,
"EHLO", 4, 0, STREAM_TOSERVER) < 0)
{
return -1;
}
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMTP,
+ if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_SMTP,
"HELO", 4, 0, STREAM_TOSERVER) < 0)
{
return -1;
}
- if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMTP,
+ if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_SMTP,
"QUIT", 4, 0, STREAM_TOSERVER) < 0)
{
return -1;
@@ -4840,8 +4840,8 @@
printf("smtp-mime file name is incorrect");
goto end;
}
- if (FileSize(file) != filesize){
- printf("smtp-mime file size %"PRIu64" is incorrect", FileSize(file));
+ if (FileTrackedSize(file) != filesize){
+ printf("smtp-mime file size %"PRIu64" is incorrect", FileDataSize(file));
goto end;
}
static uint8_t org_binary[] = {
@@ -5127,7 +5127,7 @@
FAIL_IF(file == NULL);
ret = SMTPProcessDataChunk((uint8_t *)mimemsg, sizeof(mimemsg), state);
FAIL_IF(ret != 0);
- FAIL_IF((uint32_t)FileSize(file) != 106);
+ FAIL_IF((uint32_t)FileDataSize(file) != 106);
SMTPStateFree(smtp_state);
FLOW_DESTROY(&f);
PASS;
diff -Nru suricata-3.2/src/app-layer-ssl.c suricata-3.2.1/src/app-layer-ssl.c
--- suricata-3.2/src/app-layer-ssl.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-ssl.c 2017-02-15 08:54:12.000000000 +0100
@@ -67,6 +67,7 @@
{ "MULTIPLE_SNI_EXTENSIONS", TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS },
{ "INVALID_SNI_TYPE", TLS_DECODER_EVENT_INVALID_SNI_TYPE },
{ "INVALID_SNI_LENGTH", TLS_DECODER_EVENT_INVALID_SNI_LENGTH },
+ { "TOO_MANY_RECORDS_IN_PACKET", TLS_DECODER_EVENT_TOO_MANY_RECORDS_IN_PACKET },
/* certificate decoding messages */
{ "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE },
{ "CERTIFICATE_MISSING_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT },
@@ -131,6 +132,8 @@
#define TLS_HB_REQUEST 1
#define TLS_HB_RESPONSE 2
+#define SSL_PACKET_MAX_RECORDS 255
+
#define HAS_SPACE(n) ((uint32_t)((input) + (n) - (initial_input)) > (uint32_t)(input_len)) ? 0 : 1
static void SSLParserReset(SSLState *ssl_state)
@@ -232,6 +235,13 @@
return TLS_HANDSHAKE_DONE;
}
+ if (direction == STREAM_TOSERVER &&
+ (ssl_state->server_connp.cert0_subject != NULL ||
+ ssl_state->server_connp.cert0_issuerdn != NULL))
+ {
+ return TLS_STATE_CERT_READY;
+ }
+
return TLS_STATE_IN_PROGRESS;
}
@@ -275,8 +285,9 @@
input += compression_methods_length;
+ /* extensions are optional (RFC5246 section 7.4.1.2) */
if (!(HAS_SPACE(2)))
- goto invalid_length;
+ goto end;
uint16_t extensions_len = input[0] << 8 | input[1];
input += 2;
@@ -438,6 +449,7 @@
ssl_state->curr_connp->trec_len = 0;
/* error, skip packet */
parsed += input_len;
+ (void)parsed; /* for scan-build */
ssl_state->curr_connp->bytes_processed += input_len;
return -1;
}
@@ -1254,6 +1266,7 @@
parsed += retval;
input_len -= retval;
+ (void)input_len; /* for scan-build */
if (ssl_state->curr_connp->bytes_processed ==
ssl_state->curr_connp->record_length +
@@ -1364,11 +1377,12 @@
/* if we have more than one record */
while (input_len > 0) {
- if (counter++ == 30) {
+ if (counter++ == SSL_PACKET_MAX_RECORDS) {
SCLogDebug("Looks like we have looped quite a bit. Reset state "
"and get out of here");
SSLParserReset(ssl_state);
- SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_SSL_RECORD);
+ SSLSetEvent(ssl_state,
+ TLS_DECODER_EVENT_TOO_MANY_RECORDS_IN_PACKET);
return -1;
}
@@ -1761,12 +1775,12 @@
ALPROTO_TLS,
0, 3,
STREAM_TOSERVER,
- SSLProbingParser);
+ SSLProbingParser, NULL);
} else {
AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_TLS,
0, 3,
- SSLProbingParser);
+ SSLProbingParser, NULL);
}
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol",
diff -Nru suricata-3.2/src/app-layer-ssl.h suricata-3.2.1/src/app-layer-ssl.h
--- suricata-3.2/src/app-layer-ssl.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-ssl.h 2017-02-15 08:54:12.000000000 +0100
@@ -46,6 +46,7 @@
TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS,
TLS_DECODER_EVENT_INVALID_SNI_TYPE,
TLS_DECODER_EVENT_INVALID_SNI_LENGTH,
+ TLS_DECODER_EVENT_TOO_MANY_RECORDS_IN_PACKET,
/* Certificates decoding messages */
TLS_DECODER_EVENT_INVALID_CERTIFICATE,
TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT,
@@ -58,8 +59,9 @@
enum {
TLS_STATE_IN_PROGRESS = 0,
- TLS_HANDSHAKE_DONE = 1,
- TLS_STATE_FINISHED = 2
+ TLS_STATE_CERT_READY = 1,
+ TLS_HANDSHAKE_DONE = 2,
+ TLS_STATE_FINISHED = 3
};
/* Flag to indicate that server will now on send encrypted msgs */
diff -Nru suricata-3.2/src/app-layer-template.c suricata-3.2.1/src/app-layer-template.c
--- suricata-3.2/src/app-layer-template.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/app-layer-template.c 2017-02-15 08:54:12.000000000 +0100
@@ -472,21 +472,21 @@
SCLogNotice("Unittest mode, registeringd default configuration.");
AppLayerProtoDetectPPRegister(IPPROTO_TCP, TEMPLATE_DEFAULT_PORT,
ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN, STREAM_TOSERVER,
- TemplateProbingParser);
+ TemplateProbingParser, NULL);
}
else {
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN,
- TemplateProbingParser)) {
+ TemplateProbingParser, NULL)) {
SCLogNotice("No echo app-layer configuration, enabling echo"
" detection TCP detection on port %s.",
TEMPLATE_DEFAULT_PORT);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
TEMPLATE_DEFAULT_PORT, ALPROTO_TEMPLATE, 0,
TEMPLATE_MIN_FRAME_LEN, STREAM_TOSERVER,
- TemplateProbingParser);
+ TemplateProbingParser, NULL);
}
}
diff -Nru suricata-3.2/src/decode-afl.c suricata-3.2.1/src/decode-afl.c
--- suricata-3.2/src/decode-afl.c 1970-01-01 01:00:00.000000000 +0100
+++ suricata-3.2.1/src/decode-afl.c 2017-02-15 08:54:12.000000000 +0100
@@ -0,0 +1,167 @@
+/* Copyright (C) 2007-2017 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 "suricata-common.h"
+#include "suricata.h"
+#include "conf.h"
+#include "decode.h"
+#include "util-debug.h"
+#include "util-mem.h"
+#include "app-layer-detect-proto.h"
+#include "app-layer.h"
+#include "tm-threads.h"
+#include "util-error.h"
+#include "util-print.h"
+#include "tmqh-packetpool.h"
+#include "util-profiling.h"
+#include "pkt-var.h"
+#include "util-mpm-ac.h"
+
+#include "output.h"
+#include "output-flow.h"
+
+#include "defrag.h"
+#include "flow.h"
+
+#ifdef AFLFUZZ_DECODER
+
+/* stateful processing of data as packets. Because AFL in case of a
+ * crash will only safe the last input, we dump all the inputs to a
+ * directory 'dump' with a unique timestamp for the serie and an
+ * incrementing 'id' so that we can 'replay' it in
+ * DecoderParseDataFromFileSerie().
+ */
+int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder) {
+ uint8_t buffer[65536];
+
+ struct timeval ts;
+ memset(&ts, 0, sizeof(ts));
+ gettimeofday(&ts, NULL);
+
+ uint32_t cnt = 0;
+
+ DefragInit();
+ FlowInitConfig(FLOW_QUIET);
+
+ ThreadVars tv;
+ memset(&tv, 0, sizeof(tv));
+ DecodeThreadVars *dtv = DecodeThreadVarsAlloc(&tv);
+ DecodeRegisterPerfCounters(dtv, &tv);
+ StatsSetupPrivate(&tv);
+ PacketQueue pq;
+ memset(&pq, 0, sizeof(pq));
+
+#ifdef AFLFUZZ_PERSISTANT_MODE
+ while (__AFL_LOOP(1000)) {
+ /* reset state */
+ memset(buffer, 0, sizeof(buffer));
+#endif /* AFLFUZZ_PERSISTANT_MODE */
+
+
+ FILE *fp = fopen(filename, "r");
+ BUG_ON(fp == NULL);
+
+ size_t size = fread(&buffer, 1, sizeof(buffer), fp);
+ char outfilename[256];
+ snprintf(outfilename, sizeof(outfilename), "dump/%u-%u.%u", (uint)ts.tv_sec, (uint)ts.tv_usec, cnt);
+ FILE *out_fp = fopen(outfilename, "w");
+ BUG_ON(out_fp == NULL);
+ (void)fwrite(buffer, size, 1, out_fp);
+ fclose(out_fp);
+
+ Packet *p = PacketGetFromAlloc();
+ if (p != NULL) {
+ PacketSetData(p, buffer, size);
+ (void) Decoder (&tv, dtv, p, buffer, size, &pq);
+ while (1) {
+ Packet *extra_p = PacketDequeue(&pq);
+ if (unlikely(extra_p == NULL))
+ break;
+ PacketFree(extra_p);
+ }
+ PacketFree(p);
+ }
+ fclose(fp);
+ cnt++;
+
+#ifdef AFLFUZZ_PERSISTANT_MODE
+ }
+#endif /* AFLFUZZ_PERSISTANT_MODE */
+
+ /* if we get here there was no crash, so we can remove our files */
+ uint32_t x = 0;
+ for (x = 0; x < cnt; x++) {
+ char rmfilename[256];
+ snprintf(rmfilename, sizeof(rmfilename), "dump/%u-%u.%u", (uint)ts.tv_sec, (uint)ts.tv_usec, x);
+ unlink(rmfilename);
+ }
+
+ DecodeThreadVarsFree(&tv, dtv);
+ FlowShutdown();
+ DefragDestroy();
+ return 0;
+}
+
+/* load a serie of files generated by DecoderParseDataFromFile() in
+ * the same order as it was produced. */
+int DecoderParseDataFromFileSerie(char *fileprefix, DecoderFunc Decoder)
+{
+ uint8_t buffer[65536];
+ uint32_t cnt = 0;
+
+ DefragInit();
+ FlowInitConfig(FLOW_QUIET);
+ ThreadVars tv;
+ memset(&tv, 0, sizeof(tv));
+ DecodeThreadVars *dtv = DecodeThreadVarsAlloc(&tv);
+ DecodeRegisterPerfCounters(dtv, &tv);
+ StatsSetupPrivate(&tv);
+ PacketQueue pq;
+ memset(&pq, 0, sizeof(pq));
+
+ char filename[256];
+ snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
+ FILE *fp;
+ while ((fp = fopen(filename, "r")) != NULL)
+ {
+ memset(buffer, 0, sizeof(buffer));
+
+ size_t size = fread(&buffer, 1, sizeof(buffer), fp);
+
+ Packet *p = PacketGetFromAlloc();
+ if (p != NULL) {
+ PacketSetData(p, buffer, size);
+ (void) Decoder (&tv, dtv, p, buffer, size, &pq);
+ while (1) {
+ Packet *extra_p = PacketDequeue(&pq);
+ if (unlikely(extra_p == NULL))
+ break;
+ PacketFree(extra_p);
+ }
+ PacketFree(p);
+ }
+ fclose(fp);
+ cnt++;
+ snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
+ }
+ DecodeThreadVarsFree(&tv, dtv);
+ FlowShutdown();
+ DefragDestroy();
+ return 0;
+}
+#endif /* AFLFUZZ_DECODER */
+
diff -Nru suricata-3.2/src/decode.c suricata-3.2.1/src/decode.c
--- suricata-3.2/src/decode.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/decode.c 2017-02-15 08:54:12.000000000 +0100
@@ -600,55 +600,6 @@
s->counter_ips_replaced = StatsRegisterCounter("ips.replaced", tv);
}
-#ifdef AFLFUZZ_DECODER
-int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder) {
- uint8_t buffer[65536];
- int result = 1;
-
-#ifdef AFLFUZZ_PERSISTANT_MODE
- while (__AFL_LOOP(1000)) {
- /* reset state */
- memset(buffer, 0, sizeof(buffer));
-#endif /* AFLFUZZ_PERSISTANT_MODE */
-
- FILE *fp = fopen(filename, "r");
- BUG_ON(fp == NULL);
-
- ThreadVars tv;
- memset(&tv, 0, sizeof(tv));
- DecodeThreadVars *dtv = DecodeThreadVarsAlloc(&tv);
- DecodeRegisterPerfCounters(dtv, &tv);
- StatsSetupPrivate(&tv);
-
- while (1) {
- int done = 0;
- size_t result = fread(&buffer, 1, sizeof(buffer), fp);
- if (result < sizeof(buffer))
- done = 1;
-
- Packet *p = PacketGetFromAlloc();
- if (p != NULL) {
- (void) Decoder (&tv, dtv, p, buffer, result, NULL);
- PacketFree(p);
- }
-
- if (done)
- break;
- }
- DecodeThreadVarsFree(&tv, dtv);
-
- fclose(fp);
-
-#ifdef AFLFUZZ_PERSISTANT_MODE
- }
-#endif /* AFLFUZZ_PERSISTANT_MODE */
-
- result = 0;
- return result;
-
-}
-#endif /* AFLFUZZ_DECODER */
-
/**
* @}
*/
diff -Nru suricata-3.2/src/decode.h suricata-3.2.1/src/decode.h
--- suricata-3.2/src/decode.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/decode.h 2017-02-15 08:54:12.000000000 +0100
@@ -594,7 +594,12 @@
#endif
Packet;
-#define DEFAULT_PACKET_SIZE (1500 + ETHERNET_HEADER_LEN)
+/** highest mtu of the interfaces we monitor */
+extern int g_default_mtu;
+#define DEFAULT_MTU 1500
+#define MINIMUM_MTU 68 /**< ipv4 minimum: rfc791 */
+
+#define DEFAULT_PACKET_SIZE (DEFAULT_MTU + ETHERNET_HEADER_LEN)
/* storage: maximum ip packet size + link header */
#define MAX_PAYLOAD_SIZE (IPV6_HEADER_LEN + 65536 + 28)
uint32_t default_packet_size;
@@ -953,6 +958,7 @@
uint8_t *pkt, uint16_t len, PacketQueue *pq);
int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder);
+int DecoderParseDataFromFileSerie(char *fileprefix, DecoderFunc Decoder);
#endif
/** \brief Set the No payload inspection Flag for the packet.
diff -Nru suricata-3.2/src/decode-icmpv6.c suricata-3.2.1/src/decode-icmpv6.c
--- suricata-3.2/src/decode-icmpv6.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/decode-icmpv6.c 2017-02-15 08:54:12.000000000 +0100
@@ -254,7 +254,7 @@
SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u",
p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq);
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
} else {
p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id;
@@ -265,37 +265,37 @@
break;
case ND_ROUTER_SOLICIT:
SCLogDebug("ND_ROUTER_SOLICIT");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_ROUTER_ADVERT:
SCLogDebug("ND_ROUTER_ADVERT");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_NEIGHBOR_SOLICIT:
SCLogDebug("ND_NEIGHBOR_SOLICIT");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_NEIGHBOR_ADVERT:
SCLogDebug("ND_NEIGHBOR_ADVERT");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case ND_REDIRECT:
SCLogDebug("ND_REDIRECT");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
break;
case MLD_LISTENER_QUERY:
SCLogDebug("MLD_LISTENER_QUERY");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
if (IPV6_GET_HLIM(p) != 1) {
@@ -304,7 +304,7 @@
break;
case MLD_LISTENER_REPORT:
SCLogDebug("MLD_LISTENER_REPORT");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
if (IPV6_GET_HLIM(p) != 1) {
@@ -313,13 +313,136 @@
break;
case MLD_LISTENER_REDUCTION:
SCLogDebug("MLD_LISTENER_REDUCTION");
- if (p->icmpv6h->code != 0) {
+ if (ICMPV6_GET_CODE(p) != 0) {
ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
}
if (IPV6_GET_HLIM(p) != 1) {
ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL);
}
break;
+ case ICMP6_RR:
+ SCLogDebug("ICMP6_RR");
+ if (ICMPV6_GET_CODE(p) > 2 && ICMPV6_GET_CODE(p) != 255) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case ICMP6_NI_QUERY:
+ SCLogDebug("ICMP6_NI_QUERY");
+ if (ICMPV6_GET_CODE(p) > 2) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case ICMP6_NI_REPLY:
+ SCLogDebug("ICMP6_NI_REPLY");
+ if (ICMPV6_GET_CODE(p) > 2) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case ND_INVERSE_SOLICIT:
+ SCLogDebug("ND_INVERSE_SOLICIT");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case ND_INVERSE_ADVERT:
+ SCLogDebug("ND_INVERSE_ADVERT");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case MLD_V2_LIST_REPORT:
+ SCLogDebug("MLD_V2_LIST_REPORT");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case HOME_AGENT_AD_REQUEST:
+ SCLogDebug("HOME_AGENT_AD_REQUEST");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case HOME_AGENT_AD_REPLY:
+ SCLogDebug("HOME_AGENT_AD_REPLY");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case MOBILE_PREFIX_SOLICIT:
+ SCLogDebug("MOBILE_PREFIX_SOLICIT");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case MOBILE_PREFIX_ADVERT:
+ SCLogDebug("MOBILE_PREFIX_ADVERT");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case CERT_PATH_SOLICIT:
+ SCLogDebug("CERT_PATH_SOLICIT");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case CERT_PATH_ADVERT:
+ SCLogDebug("CERT_PATH_ADVERT");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case ICMP6_MOBILE_EXPERIMENTAL:
+ SCLogDebug("ICMP6_MOBILE_EXPERIMENTAL");
+ break;
+ case MC_ROUTER_ADVERT:
+ SCLogDebug("MC_ROUTER_ADVERT");
+ break;
+ case MC_ROUTER_SOLICIT:
+ SCLogDebug("MC_ROUTER_SOLICIT");
+ break;
+ case MC_ROUTER_TERMINATE:
+ SCLogDebug("MC_ROUTER_TERMINATE");
+ break;
+ case FMIPV6_MSG:
+ SCLogDebug("FMIPV6_MSG");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case RPL_CONTROL_MSG:
+ SCLogDebug("RPL_CONTROL_MSG");
+ if (ICMPV6_GET_CODE(p) > 3 && ICMPV6_GET_CODE(p) < 128) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ if (ICMPV6_GET_CODE(p) > 132) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case LOCATOR_UDATE_MSG:
+ SCLogDebug("LOCATOR_UDATE_MSG");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case DUPL_ADDR_REQUEST:
+ SCLogDebug("DUPL_ADDR_REQUEST");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case DUPL_ADDR_CONFIRM:
+ SCLogDebug("DUPL_ADDR_CONFIRM");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
+ case MPL_CONTROL_MSG:
+ SCLogDebug("MPL_CONTROL_MSG");
+ if (ICMPV6_GET_CODE(p) != 0) {
+ ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+ }
+ break;
default:
/* Various range taken from:
* http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-2
diff -Nru suricata-3.2/src/decode-icmpv6.h suricata-3.2.1/src/decode-icmpv6.h
--- suricata-3.2/src/decode-icmpv6.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/decode-icmpv6.h 2017-02-15 08:54:12.000000000 +0100
@@ -53,6 +53,29 @@
#define ND_NEIGHBOR_ADVERT 136
#define ND_REDIRECT 137
+#define ICMP6_RR 138
+#define ICMP6_NI_QUERY 139
+#define ICMP6_NI_REPLY 140
+#define ND_INVERSE_SOLICIT 141
+#define ND_INVERSE_ADVERT 142
+#define MLD_V2_LIST_REPORT 143
+#define HOME_AGENT_AD_REQUEST 144
+#define HOME_AGENT_AD_REPLY 145
+#define MOBILE_PREFIX_SOLICIT 146
+#define MOBILE_PREFIX_ADVERT 147
+#define CERT_PATH_SOLICIT 148
+#define CERT_PATH_ADVERT 149
+#define ICMP6_MOBILE_EXPERIMENTAL 150
+#define MC_ROUTER_ADVERT 151
+#define MC_ROUTER_SOLICIT 152
+#define MC_ROUTER_TERMINATE 153
+#define FMIPV6_MSG 154
+#define RPL_CONTROL_MSG 155
+#define LOCATOR_UDATE_MSG 156
+#define DUPL_ADDR_REQUEST 157
+#define DUPL_ADDR_CONFIRM 158
+#define MPL_CONTROL_MSG 159
+
/** Destination Unreachable Message (type=1) Code: */
#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
diff -Nru suricata-3.2/src/defrag.c suricata-3.2.1/src/defrag.c
--- suricata-3.2/src/defrag.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/defrag.c 2017-02-15 08:54:12.000000000 +0100
@@ -996,8 +996,8 @@
* with some payload of no particular protocol.
*/
static Packet *
-BuildTestPacket(uint16_t id, uint16_t off, int mf, const char content,
- int content_len)
+BuildTestPacket(uint8_t proto, uint16_t id, uint16_t off, int mf,
+ const char content, int content_len)
{
Packet *p = NULL;
int hlen = 20;
@@ -1023,7 +1023,7 @@
else
ip4h.ip_off = htons(off);
ip4h.ip_ttl = ttl;
- ip4h.ip_proto = IPPROTO_ICMP;
+ ip4h.ip_proto = proto;
ip4h.s_ip_src.s_addr = 0x01010101; /* 1.1.1.1 */
ip4h.s_ip_dst.s_addr = 0x02020202; /* 2.2.2.2 */
@@ -1059,7 +1059,7 @@
goto error;
if (IPV4_GET_IPTTL(p) != ttl)
goto error;
- if (IPV4_GET_IPPROTO(p) != IPPROTO_ICMP)
+ if (IPV4_GET_IPPROTO(p) != proto)
goto error;
return p;
@@ -1074,8 +1074,8 @@
uint16_t prev_hdrextlen);
static Packet *
-IPV6BuildTestPacket(uint32_t id, uint16_t off, int mf, const char content,
- int content_len)
+IPV6BuildTestPacket(uint8_t proto, uint32_t id, uint16_t off, int mf,
+ const char content, int content_len)
{
Packet *p = NULL;
uint8_t *pcontent;
@@ -1109,7 +1109,7 @@
IPV6_SET_RAW_VER(p->ip6h, 6);
/* Fragmentation header. */
IPV6FragHdr *fh = (IPV6FragHdr *)(GET_PKT_DATA(p) + sizeof(IPV6Hdr));
- fh->ip6fh_nxt = IPPROTO_ICMP;
+ fh->ip6fh_nxt = proto;
fh->ip6fh_ident = htonl(id);
fh->ip6fh_offlg = htons((off << 3) | mf);
@@ -1159,13 +1159,13 @@
DefragInit();
- p1 = BuildTestPacket(id, 0, 1, 'A', 8);
+ p1 = BuildTestPacket(IPPROTO_ICMP, id, 0, 1, 'A', 8);
if (p1 == NULL)
goto end;
- p2 = BuildTestPacket(id, 1, 1, 'B', 8);
+ p2 = BuildTestPacket(IPPROTO_ICMP, id, 1, 1, 'B', 8);
if (p2 == NULL)
goto end;
- p3 = BuildTestPacket(id, 2, 0, 'C', 3);
+ p3 = BuildTestPacket(IPPROTO_ICMP, id, 2, 0, 'C', 3);
if (p3 == NULL)
goto end;
@@ -1236,13 +1236,13 @@
DefragInit();
- p1 = BuildTestPacket(id, 0, 1, 'A', 8);
+ p1 = BuildTestPacket(IPPROTO_ICMP, id, 0, 1, 'A', 8);
if (p1 == NULL)
goto end;
- p2 = BuildTestPacket(id, 1, 1, 'B', 8);
+ p2 = BuildTestPacket(IPPROTO_ICMP, id, 1, 1, 'B', 8);
if (p2 == NULL)
goto end;
- p3 = BuildTestPacket(id, 2, 0, 'C', 3);
+ p3 = BuildTestPacket(IPPROTO_ICMP, id, 2, 0, 'C', 3);
if (p3 == NULL)
goto end;
@@ -1308,13 +1308,13 @@
DefragInit();
- p1 = IPV6BuildTestPacket(id, 0, 1, 'A', 8);
+ p1 = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 0, 1, 'A', 8);
if (p1 == NULL)
goto end;
- p2 = IPV6BuildTestPacket(id, 1, 1, 'B', 8);
+ p2 = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 1, 1, 'B', 8);
if (p2 == NULL)
goto end;
- p3 = IPV6BuildTestPacket(id, 2, 0, 'C', 3);
+ p3 = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 2, 0, 'C', 3);
if (p3 == NULL)
goto end;
@@ -1378,13 +1378,13 @@
if (dc == NULL)
goto end;
- p1 = IPV6BuildTestPacket(id, 0, 1, 'A', 8);
+ p1 = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 0, 1, 'A', 8);
if (p1 == NULL)
goto end;
- p2 = IPV6BuildTestPacket(id, 1, 1, 'B', 8);
+ p2 = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 1, 1, 'B', 8);
if (p2 == NULL)
goto end;
- p3 = IPV6BuildTestPacket(id, 2, 0, 'C', 3);
+ p3 = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 2, 0, 'C', 3);
if (p3 == NULL)
goto end;
@@ -1452,59 +1452,59 @@
*/
/* A*24 at 0. */
- packets[0] = BuildTestPacket(id, 0, 1, 'A', 24);
+ packets[0] = BuildTestPacket(IPPROTO_ICMP, id, 0, 1, 'A', 24);
/* B*15 at 32. */
- packets[1] = BuildTestPacket(id, 32 >> 3, 1, 'B', 16);
+ packets[1] = BuildTestPacket(IPPROTO_ICMP, id, 32 >> 3, 1, 'B', 16);
/* C*24 at 48. */
- packets[2] = BuildTestPacket(id, 48 >> 3, 1, 'C', 24);
+ packets[2] = BuildTestPacket(IPPROTO_ICMP, id, 48 >> 3, 1, 'C', 24);
/* D*8 at 80. */
- packets[3] = BuildTestPacket(id, 80 >> 3, 1, 'D', 8);
+ packets[3] = BuildTestPacket(IPPROTO_ICMP, id, 80 >> 3, 1, 'D', 8);
/* E*16 at 104. */
- packets[4] = BuildTestPacket(id, 104 >> 3, 1, 'E', 16);
+ packets[4] = BuildTestPacket(IPPROTO_ICMP, id, 104 >> 3, 1, 'E', 16);
/* F*24 at 120. */
- packets[5] = BuildTestPacket(id, 120 >> 3, 1, 'F', 24);
+ packets[5] = BuildTestPacket(IPPROTO_ICMP, id, 120 >> 3, 1, 'F', 24);
/* G*16 at 144. */
- packets[6] = BuildTestPacket(id, 144 >> 3, 1, 'G', 16);
+ packets[6] = BuildTestPacket(IPPROTO_ICMP, id, 144 >> 3, 1, 'G', 16);
/* H*16 at 160. */
- packets[7] = BuildTestPacket(id, 160 >> 3, 1, 'H', 16);
+ packets[7] = BuildTestPacket(IPPROTO_ICMP, id, 160 >> 3, 1, 'H', 16);
/* I*8 at 176. */
- packets[8] = BuildTestPacket(id, 176 >> 3, 1, 'I', 8);
+ packets[8] = BuildTestPacket(IPPROTO_ICMP, id, 176 >> 3, 1, 'I', 8);
/*
* Overlapping subsequent fragments.
*/
/* J*32 at 8. */
- packets[9] = BuildTestPacket(id, 8 >> 3, 1, 'J', 32);
+ packets[9] = BuildTestPacket(IPPROTO_ICMP, id, 8 >> 3, 1, 'J', 32);
/* K*24 at 48. */
- packets[10] = BuildTestPacket(id, 48 >> 3, 1, 'K', 24);
+ packets[10] = BuildTestPacket(IPPROTO_ICMP, id, 48 >> 3, 1, 'K', 24);
/* L*24 at 72. */
- packets[11] = BuildTestPacket(id, 72 >> 3, 1, 'L', 24);
+ packets[11] = BuildTestPacket(IPPROTO_ICMP, id, 72 >> 3, 1, 'L', 24);
/* M*24 at 96. */
- packets[12] = BuildTestPacket(id, 96 >> 3, 1, 'M', 24);
+ packets[12] = BuildTestPacket(IPPROTO_ICMP, id, 96 >> 3, 1, 'M', 24);
/* N*8 at 128. */
- packets[13] = BuildTestPacket(id, 128 >> 3, 1, 'N', 8);
+ packets[13] = BuildTestPacket(IPPROTO_ICMP, id, 128 >> 3, 1, 'N', 8);
/* O*8 at 152. */
- packets[14] = BuildTestPacket(id, 152 >> 3, 1, 'O', 8);
+ packets[14] = BuildTestPacket(IPPROTO_ICMP, id, 152 >> 3, 1, 'O', 8);
/* P*8 at 160. */
- packets[15] = BuildTestPacket(id, 160 >> 3, 1, 'P', 8);
+ packets[15] = BuildTestPacket(IPPROTO_ICMP, id, 160 >> 3, 1, 'P', 8);
/* Q*16 at 176. */
- packets[16] = BuildTestPacket(id, 176 >> 3, 0, 'Q', 16);
+ packets[16] = BuildTestPacket(IPPROTO_ICMP, id, 176 >> 3, 0, 'Q', 16);
default_policy = policy;
@@ -1587,59 +1587,59 @@
*/
/* A*24 at 0. */
- packets[0] = IPV6BuildTestPacket(id, 0, 1, 'A', 24);
+ packets[0] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 0, 1, 'A', 24);
/* B*15 at 32. */
- packets[1] = IPV6BuildTestPacket(id, 32 >> 3, 1, 'B', 16);
+ packets[1] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 32 >> 3, 1, 'B', 16);
/* C*24 at 48. */
- packets[2] = IPV6BuildTestPacket(id, 48 >> 3, 1, 'C', 24);
+ packets[2] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 48 >> 3, 1, 'C', 24);
/* D*8 at 80. */
- packets[3] = IPV6BuildTestPacket(id, 80 >> 3, 1, 'D', 8);
+ packets[3] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 80 >> 3, 1, 'D', 8);
/* E*16 at 104. */
- packets[4] = IPV6BuildTestPacket(id, 104 >> 3, 1, 'E', 16);
+ packets[4] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 104 >> 3, 1, 'E', 16);
/* F*24 at 120. */
- packets[5] = IPV6BuildTestPacket(id, 120 >> 3, 1, 'F', 24);
+ packets[5] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 120 >> 3, 1, 'F', 24);
/* G*16 at 144. */
- packets[6] = IPV6BuildTestPacket(id, 144 >> 3, 1, 'G', 16);
+ packets[6] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 144 >> 3, 1, 'G', 16);
/* H*16 at 160. */
- packets[7] = IPV6BuildTestPacket(id, 160 >> 3, 1, 'H', 16);
+ packets[7] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 160 >> 3, 1, 'H', 16);
/* I*8 at 176. */
- packets[8] = IPV6BuildTestPacket(id, 176 >> 3, 1, 'I', 8);
+ packets[8] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 176 >> 3, 1, 'I', 8);
/*
* Overlapping subsequent fragments.
*/
/* J*32 at 8. */
- packets[9] = IPV6BuildTestPacket(id, 8 >> 3, 1, 'J', 32);
+ packets[9] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 8 >> 3, 1, 'J', 32);
/* K*24 at 48. */
- packets[10] = IPV6BuildTestPacket(id, 48 >> 3, 1, 'K', 24);
+ packets[10] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 48 >> 3, 1, 'K', 24);
/* L*24 at 72. */
- packets[11] = IPV6BuildTestPacket(id, 72 >> 3, 1, 'L', 24);
+ packets[11] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 72 >> 3, 1, 'L', 24);
/* M*24 at 96. */
- packets[12] = IPV6BuildTestPacket(id, 96 >> 3, 1, 'M', 24);
+ packets[12] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 96 >> 3, 1, 'M', 24);
/* N*8 at 128. */
- packets[13] = IPV6BuildTestPacket(id, 128 >> 3, 1, 'N', 8);
+ packets[13] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 128 >> 3, 1, 'N', 8);
/* O*8 at 152. */
- packets[14] = IPV6BuildTestPacket(id, 152 >> 3, 1, 'O', 8);
+ packets[14] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 152 >> 3, 1, 'O', 8);
/* P*8 at 160. */
- packets[15] = IPV6BuildTestPacket(id, 160 >> 3, 1, 'P', 8);
+ packets[15] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 160 >> 3, 1, 'P', 8);
/* Q*16 at 176. */
- packets[16] = IPV6BuildTestPacket(id, 176 >> 3, 0, 'Q', 16);
+ packets[16] = IPV6BuildTestPacket(IPPROTO_ICMPV6, id, 176 >> 3, 0, 'Q', 16);
default_policy = policy;
@@ -2125,7 +2125,7 @@
/* Load in 16 packets. */
for (i = 0; i < 16; i++) {
- Packet *p = BuildTestPacket(i, 0, 1, 'A' + i, 16);
+ Packet *p = BuildTestPacket(IPPROTO_ICMP,i, 0, 1, 'A' + i, 16);
if (p == NULL)
goto end;
@@ -2141,7 +2141,7 @@
/* Build a new packet but push the timestamp out by our timeout.
* This should force our previous fragments to be timed out. */
- Packet *p = BuildTestPacket(99, 0, 1, 'A' + i, 16);
+ Packet *p = BuildTestPacket(IPPROTO_ICMP, 99, 0, 1, 'A' + i, 16);
if (p == NULL)
goto end;
@@ -2189,7 +2189,7 @@
goto end;
/* This packet has an offset > 0, more frags set to 0 and no data. */
- p = BuildTestPacket(id, 1, 0, 'A', 0);
+ p = BuildTestPacket(IPPROTO_ICMP, id, 1, 0, 'A', 0);
if (p == NULL)
goto end;
@@ -2228,7 +2228,7 @@
/* Create a fragment that would extend past the max allowable size
* for an IPv4 packet. */
- p = BuildTestPacket(1, 8183, 0, 'A', 71);
+ p = BuildTestPacket(IPPROTO_ICMP, 1, 8183, 0, 'A', 71);
if (p == NULL)
goto end;
@@ -2267,10 +2267,10 @@
DefragInit();
- p1 = BuildTestPacket(1, 0, 1, 'A', 8);
+ p1 = BuildTestPacket(IPPROTO_ICMP, 1, 0, 1, 'A', 8);
if (p1 == NULL)
goto end;
- p2 = BuildTestPacket(1, 1, 0, 'B', 8);
+ p2 = BuildTestPacket(IPPROTO_ICMP, 1, 1, 0, 'B', 8);
if (p2 == NULL)
goto end;
@@ -2313,10 +2313,10 @@
DefragInit();
- p1 = BuildTestPacket(1, 0, 1, 'A', 8);
+ p1 = BuildTestPacket(IPPROTO_ICMP, 1, 0, 1, 'A', 8);
if (p1 == NULL)
goto end;
- p2 = BuildTestPacket(1, 1, 0, 'B', 8);
+ p2 = BuildTestPacket(IPPROTO_ICMP, 1, 1, 0, 'B', 8);
if (p2 == NULL)
goto end;
@@ -2361,7 +2361,7 @@
/* Build a packet, its not a fragment but shouldn't matter for
* this test. */
- p1 = BuildTestPacket(id, 0, 0, 'A', 8);
+ p1 = BuildTestPacket(IPPROTO_ICMP, id, 0, 0, 'A', 8);
if (p1 == NULL) {
goto end;
}
@@ -2431,9 +2431,9 @@
DefragInit();
- Packet *p1 = BuildTestPacket(ip_id, 2, 1, 'C', 8);
- Packet *p2 = BuildTestPacket(ip_id, 0, 1, 'A', 8);
- Packet *p3 = BuildTestPacket(ip_id, 1, 0, 'B', 8);
+ Packet *p1 = BuildTestPacket(IPPROTO_ICMP, ip_id, 2, 1, 'C', 8);
+ Packet *p2 = BuildTestPacket(IPPROTO_ICMP, ip_id, 0, 1, 'A', 8);
+ Packet *p3 = BuildTestPacket(IPPROTO_ICMP, ip_id, 1, 0, 'B', 8);
if (p1 == NULL || p2 == NULL || p3 == NULL) {
goto end;
}
@@ -2495,9 +2495,9 @@
DefragInit();
- Packet *p1 = IPV6BuildTestPacket(ip_id, 2, 1, 'C', 8);
- Packet *p2 = IPV6BuildTestPacket(ip_id, 0, 1, 'A', 8);
- Packet *p3 = IPV6BuildTestPacket(ip_id, 1, 0, 'B', 8);
+ Packet *p1 = IPV6BuildTestPacket(IPPROTO_ICMPV6, ip_id, 2, 1, 'C', 8);
+ Packet *p2 = IPV6BuildTestPacket(IPPROTO_ICMPV6, ip_id, 0, 1, 'A', 8);
+ Packet *p3 = IPV6BuildTestPacket(IPPROTO_ICMPV6, ip_id, 1, 0, 'B', 8);
if (p1 == NULL || p2 == NULL || p3 == NULL) {
goto end;
}
@@ -2542,6 +2542,39 @@
return retval;
}
+/**
+ * \brief Test that fragments that match other than the proto don't
+ * actually get matched.
+ */
+static int DefragTestBadProto(void)
+{
+ Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
+ int id = 12;
+
+ DefragInit();
+
+ p1 = BuildTestPacket(IPPROTO_ICMP, id, 0, 1, 'A', 8);
+ FAIL_IF_NULL(p1);
+ p2 = BuildTestPacket(IPPROTO_UDP, id, 1, 1, 'B', 8);
+ FAIL_IF_NULL(p2);
+ p3 = BuildTestPacket(IPPROTO_ICMP, id, 2, 0, 'C', 3);
+ FAIL_IF_NULL(p3);
+
+ FAIL_IF_NOT_NULL(Defrag(NULL, NULL, p1, NULL));
+ FAIL_IF_NOT_NULL(Defrag(NULL, NULL, p2, NULL));
+ FAIL_IF_NOT_NULL(Defrag(NULL, NULL, p3, NULL));
+
+ if (p1 != NULL)
+ SCFree(p1);
+ if (p2 != NULL)
+ SCFree(p2);
+ if (p3 != NULL)
+ SCFree(p3);
+
+ DefragDestroy();
+ PASS;
+}
+
#endif /* UNITTESTS */
void
@@ -2583,6 +2616,7 @@
UtRegisterTest("DefragTimeoutTest", DefragTimeoutTest);
UtRegisterTest("DefragMfIpv4Test", DefragMfIpv4Test);
UtRegisterTest("DefragMfIpv6Test", DefragMfIpv6Test);
+ UtRegisterTest("DefragTestBadProto", DefragTestBadProto);
#endif /* UNITTESTS */
}
diff -Nru suricata-3.2/src/defrag.h suricata-3.2.1/src/defrag.h
--- suricata-3.2/src/defrag.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/defrag.h 2017-02-15 08:54:12.000000000 +0100
@@ -84,6 +84,8 @@
uint32_t id; /**< IP ID for this tracker. 32 bits for IPv6, 16
* for IPv4. */
+ uint8_t proto; /**< IP protocol for this tracker. */
+
uint8_t policy; /**< Reassembly policy this tracker will use. */
uint8_t af; /**< Address family for this tracker, AF_INET or
diff -Nru suricata-3.2/src/defrag-hash.c suricata-3.2.1/src/defrag-hash.c
--- suricata-3.2/src/defrag-hash.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/defrag-hash.c 2017-02-15 08:54:12.000000000 +0100
@@ -92,6 +92,7 @@
dt->id = (int32_t)IPV6_EXTHDR_GET_FH_ID(p);
dt->af = AF_INET6;
}
+ dt->proto = IP_GET_IPPROTO(p);
dt->vlan_id[0] = p->vlan_id[0];
dt->vlan_id[1] = p->vlan_id[1];
dt->policy = DefragGetOsPolicy(p);
@@ -406,6 +407,7 @@
CMP_ADDR(&(d1)->dst_addr, &(d2)->dst)) || \
(CMP_ADDR(&(d1)->src_addr, &(d2)->dst) && \
CMP_ADDR(&(d1)->dst_addr, &(d2)->src))) && \
+ (d1)->proto == IP_GET_IPPROTO(p) && \
(d1)->id == (id) && \
(d1)->vlan_id[0] == (d2)->vlan_id[0] && \
(d1)->vlan_id[1] == (d2)->vlan_id[1])
diff -Nru suricata-3.2/src/detect-app-layer-event.c suricata-3.2.1/src/detect-app-layer-event.c
--- suricata-3.2/src/detect-app-layer-event.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-app-layer-event.c 2017-02-15 08:54:12.000000000 +0100
@@ -46,6 +46,8 @@
#include "util-unittest-helper.h"
#include "stream-tcp-util.h"
+#define MAX_ALPROTO_NAME 50
+
static int DetectAppLayerEventPktMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, const SigMatchCtx *ctx);
static int DetectAppLayerEventAppMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *,
@@ -193,10 +195,14 @@
int event_id = 0;
const char *p_idx;
uint8_t ipproto;
- char alproto_name[50];
+ char alproto_name[MAX_ALPROTO_NAME];
int r = 0;
p_idx = strchr(data->arg, '.');
+ if (strlen(data->arg) > MAX_ALPROTO_NAME) {
+ SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword is too long or malformed");
+ return -1;
+ }
strlcpy(alproto_name, data->arg, p_idx - data->arg + 1);
if (ipproto_bitarray[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8)) {
@@ -227,9 +233,13 @@
DetectAppLayerEventData *aled;
AppProto alproto;
const char *p_idx;
- char alproto_name[50];
+ char alproto_name[MAX_ALPROTO_NAME];
p_idx = strchr(arg, '.');
+ if (strlen(arg) > MAX_ALPROTO_NAME) {
+ SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword is too long or malformed");
+ return NULL;
+ }
/* + 1 for trailing \0 */
strlcpy(alproto_name, arg, p_idx - arg + 1);
diff -Nru suricata-3.2/src/detect.c suricata-3.2.1/src/detect.c
--- suricata-3.2/src/detect.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect.c 2017-02-15 08:54:12.000000000 +0100
@@ -588,6 +588,11 @@
* the decoder events sgh we have. */
if (p->proto == 0 && p->events.cnt > 0) {
SCReturnPtr(de_ctx->decoder_event_sgh, "SigGroupHead");
+ } else if (p->proto == 0) {
+ if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) {
+ /* not IP, so nothing to do */
+ SCReturnPtr(NULL, "SigGroupHead");
+ }
}
/* select the flow_gh */
@@ -953,7 +958,7 @@
if (sgh == NULL || sgh->filestore_cnt == 0) {
FileDisableStoring(pflow, direction);
}
-
+#ifdef HAVE_MAGIC
/* see if this sgh requires us to consider file magic */
if (!FileForceMagic() && (sgh == NULL ||
!(sgh->flags & SIG_GROUP_HEAD_HAVEFILEMAGIC)))
@@ -961,7 +966,7 @@
SCLogDebug("disabling magic for flow");
FileDisableMagic(pflow, direction);
}
-
+#endif
/* see if this sgh requires us to consider file md5 */
if (!FileForceMd5() && (sgh == NULL ||
!(sgh->flags & SIG_GROUP_HEAD_HAVEFILEMD5)))
@@ -1734,9 +1739,7 @@
}
if (p->flow) {
- det_ctx->flow_locked = 1;
DetectFlow(tv, de_ctx, det_ctx, p);
- det_ctx->flow_locked = 0;
} else {
DetectNoFlow(tv, de_ctx, det_ctx, p);
}
diff -Nru suricata-3.2/src/detect-csum.c suricata-3.2.1/src/detect-csum.c
--- suricata-3.2/src/detect-csum.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-csum.c 2017-02-15 08:54:12.000000000 +0100
@@ -1544,7 +1544,7 @@
printf("DetectEngineCtxInit failure\n");
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx, "alert ip any any -> any any "
diff -Nru suricata-3.2/src/detect-dns-query.c suricata-3.2.1/src/detect-dns-query.c
--- suricata-3.2/src/detect-dns-query.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-dns-query.c 2017-02-15 08:54:12.000000000 +0100
@@ -153,7 +153,7 @@
if (de_ctx == NULL) {
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
@@ -286,7 +286,7 @@
if (de_ctx == NULL) {
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
@@ -441,7 +441,7 @@
if (de_ctx == NULL) {
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
@@ -548,7 +548,7 @@
if (de_ctx == NULL) {
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
@@ -714,7 +714,7 @@
if (de_ctx == NULL) {
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
@@ -887,7 +887,7 @@
if (de_ctx == NULL) {
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
@@ -1034,7 +1034,7 @@
if (de_ctx == NULL) {
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any "
diff -Nru suricata-3.2/src/detect-engine-address.c suricata-3.2.1/src/detect-engine-address.c
--- suricata-3.2/src/detect-engine-address.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-address.c 2017-02-15 08:54:12.000000000 +0100
@@ -959,8 +959,11 @@
if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
(negate + n_set) % 2, var_list) < 0)
+ {
+ if (temp_rule_var_address != rule_var_address)
+ SCFree(temp_rule_var_address);
goto error;
-
+ }
d_set = 0;
n_set = 0;
if (temp_rule_var_address != rule_var_address)
diff -Nru suricata-3.2/src/detect-engine-alert.c suricata-3.2.1/src/detect-engine-alert.c
--- suricata-3.2/src/detect-engine-alert.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-alert.c 2017-02-15 08:54:12.000000000 +0100
@@ -327,6 +327,12 @@
* keyword context for sessions and hosts */
if (!(p->flags & PKT_PSEUDO_STREAM_END))
TagHandlePacket(de_ctx, det_ctx, p);
+
+ /* Set flag on flow to indicate that it has alerts */
+ if (p->flow != NULL && p->alerts.cnt > 0) {
+ FlowSetHasAlertsFlag(p->flow);
+ }
+
}
diff -Nru suricata-3.2/src/detect-engine.c suricata-3.2.1/src/detect-engine.c
--- suricata-3.2/src/detect-engine.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine.c 2017-02-15 08:54:12.000000000 +0100
@@ -2440,7 +2440,7 @@
} else {
DetectEngineCtx *list = master->list;
for ( ; list != NULL; list = list->next) {
- SCLogInfo("list %p tenant %u", list, list->tenant_id);
+ SCLogDebug("list %p tenant %u", list, list->tenant_id);
if (list->tenant_id == 0) {
minimal_de_ctx = list;
diff -Nru suricata-3.2/src/detect-engine-file.c suricata-3.2.1/src/detect-engine-file.c
--- suricata-3.2/src/detect-engine-file.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-file.c 2017-02-15 08:54:12.000000000 +0100
@@ -110,7 +110,7 @@
break;
}
- uint64_t file_size = FileSize(file);
+ uint64_t file_size = FileDataSize(file);
if ((s->file_flags & FILE_SIG_NEED_MAGIC) && file_size == 0) {
SCLogDebug("sig needs file content, but we don't have any");
r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
diff -Nru suricata-3.2/src/detect-engine-filedata-smtp.c suricata-3.2.1/src/detect-engine-filedata-smtp.c
--- suricata-3.2/src/detect-engine-filedata-smtp.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-filedata-smtp.c 2017-02-15 08:54:12.000000000 +0100
@@ -96,7 +96,7 @@
const uint8_t *buffer = NULL;
*buffer_len = 0;
*stream_start_offset = 0;
- uint64_t file_size = FileSize(curr_file);
+ uint64_t file_size = FileDataSize(curr_file);
if (det_ctx->smtp_buffers_list_len == 0) {
if (SMTPCreateSpace(det_ctx, 1) < 0)
@@ -160,7 +160,7 @@
det_ctx->smtp[index].offset = curr_file->content_inspected;
/* updat inspected tracker */
- curr_file->content_inspected = FileSize(curr_file);
+ curr_file->content_inspected = FileDataSize(curr_file);
SCLogDebug("content_inspected %u, offset %u", (uint)curr_file->content_inspected, (uint)det_ctx->smtp[index].offset);
diff -Nru suricata-3.2/src/detect-engine-mpm.c suricata-3.2.1/src/detect-engine-mpm.c
--- suricata-3.2/src/detect-engine-mpm.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-mpm.c 2017-02-15 08:54:12.000000000 +0100
@@ -343,7 +343,7 @@
uint16_t PatternMatchDefaultMatcher(void)
{
char *mpm_algo;
- uint16_t mpm_algo_val = DEFAULT_MPM;
+ uint16_t mpm_algo_val = mpm_default_matcher;
/* Get the mpm algo defined in config file by the user */
if ((ConfGet("mpm-algo", &mpm_algo)) == 1) {
diff -Nru suricata-3.2/src/detect-engine-payload.c suricata-3.2.1/src/detect-engine-payload.c
--- suricata-3.2/src/detect-engine-payload.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-payload.c 2017-02-15 08:54:12.000000000 +0100
@@ -214,7 +214,7 @@
int result = 0;
char sig[] = "alert tcp any any -> any any (content:\"abc\"; content:\"d\"; distance:0; within:1; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -236,7 +236,7 @@
int result = 0;
char sig[] = "alert tcp any any -> any any (content:\"abc\"; nocase; content:\"d\"; distance:0; within:1; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -258,7 +258,7 @@
int result = 0;
char sig[] = "alert tcp any any -> any any (content:\"aBc\"; nocase; content:\"abca\"; distance:-10; within:4; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -283,7 +283,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"this\"; content:\"is\"; within:6; content:\"big\"; within:8; "
"content:\"string\"; within:8; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -308,7 +308,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"this\"; content:\"is\"; within:9; content:\"big\"; within:12; "
"content:\"string\"; within:8; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -333,7 +333,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"now\"; content:\"this\"; content:\"is\"; within:12; content:\"big\"; within:8; "
"content:\"string\"; within:8; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -358,7 +358,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"thus\"; offset:8; content:\"is\"; within:6; content:\"big\"; within:8; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -384,7 +384,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"fix\"; content:\"this\"; within:6; content:!\"and\"; distance:0; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) != 1) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) != 1) {
goto end;
}
@@ -408,7 +408,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"pcre:/super/; content:\"nova\"; within:7; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -433,7 +433,7 @@
char sig[] = "alert udp any any -> any any (msg:\"crash\"; "
"byte_test:4,>,2,0,relative; sid:11;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 1) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 1) {
result = 0;
goto end;
}
@@ -458,7 +458,7 @@
char sig[] = "alert udp any any -> any any (msg:\"crash\"; "
"byte_jump:1,0,relative; sid:11;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 1) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 1) {
result = 0;
goto end;
}
@@ -483,7 +483,7 @@
char sig[] = "alert udp any any -> any any (msg:\"crash\"; "
"isdataat:10,relative; sid:11;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 1) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 1) {
result = 0;
goto end;
}
@@ -523,7 +523,7 @@
uint16_t buflen = strlen((char *)buf);
Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
int result = 0;
- uint16_t mpm_type = DEFAULT_MPM;
+ uint16_t mpm_type = mpm_default_matcher;
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"aa\"; content:\"aa\"; distance:0; content:\"aa\"; distance:0; "
@@ -605,7 +605,7 @@
//char sig[] = "alert tcp any any -> any any (content:\"User-Agent: Mozilla/5.0 (Macintosh; \"; content:\"Firefox/3.\"; distance:0; content:!\"Firefox/3.6.12\"; distance:-10; content:!\"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.6 GTB5\"; sid:1; rev:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 1) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 1) {
goto end;
}
@@ -626,7 +626,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"nova\"; isdataat:18,relative; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -649,7 +649,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"content:\"nova\"; isdataat:!20,relative; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -673,7 +673,7 @@
"content:\"%\"; depth:4; offset:0; "
"content:\"%\"; within:2; distance:1; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -702,7 +702,7 @@
"byte_extract:1,2,one,string,dec,relative; "
"content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -731,7 +731,7 @@
"byte_extract:1,2,one,string,hex,relative; "
"content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -760,7 +760,7 @@
"byte_extract:1,2,one,string,dec,relative; "
"content:\"|06 35 07 08|\"; offset:one; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -789,7 +789,7 @@
"byte_extract:1,2,one,string,dec,relative; "
"content:\"|03 04 05 06|\"; depth:one; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -818,7 +818,7 @@
"byte_extract:1,2,one,string,dec,relative; "
"content:\"|09 0A 0B 0C|\"; within:one; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -848,7 +848,7 @@
"byte_extract:1,3,two,string,dec,relative; "
"byte_test:1,=,one,two,string,dec,relative; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -878,7 +878,7 @@
"byte_jump:1,one,string,dec,relative; "
"content:\"|0D 0E 0F|\"; distance:0; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -910,7 +910,7 @@
"byte_extract:1,-4,one,string,dec,relative; "
"content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -942,7 +942,7 @@
"byte_extract:1,-3000,one,string,dec,relative; "
"content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) != 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) != 0) {
result = 0;
goto end;
}
@@ -970,7 +970,7 @@
"depth:5; sid:1;)";
p->flags |= PKT_STREAM_ADD;
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) != 1)
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) != 1)
goto end;
result = 1;
@@ -996,7 +996,7 @@
"offset:4; depth:12; sid:1;)";
p->flags |= PKT_STREAM_ADD;
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) != 1)
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) != 1)
goto end;
result = 1;
@@ -1020,7 +1020,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; "
"pcre:/^.{4}/; content:\"nova\"; within:4; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 1) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 1) {
result = 0;
goto end;
}
@@ -1041,7 +1041,7 @@
int result = 0;
char sig[] = "alert tcp any any -> any any (content:\"one\"; pcre:\"/^two/R\"; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -1062,7 +1062,7 @@
int result = 0;
char sig[] = "alert tcp any any -> any any (content:\"one\"; pcre:\"/(fiv|^two)/R\"; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) {
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0) {
result = 0;
goto end;
}
@@ -1087,7 +1087,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"crash\"; "
"content:\"message\"; byte_jump:2,-14,string,dec,relative; content:\"card\"; within:4; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0)
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0)
goto end;
result = 1;
@@ -1110,7 +1110,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"crash\"; "
"content:\"message\"; byte_test:1,=,2,-14,string,dec,relative; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0)
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0)
goto end;
result = 1;
@@ -1133,7 +1133,7 @@
char sig[] = "alert tcp any any -> any any (msg:\"crash\"; "
"content:\"message\"; byte_extract:1,-14,boom,string,dec,relative; sid:1;)";
- if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0)
+ if (UTHPacketMatchSigMpm(p, sig, mpm_default_matcher) == 0)
goto end;
result = 1;
diff -Nru suricata-3.2/src/detect-engine-siggroup.c suricata-3.2.1/src/detect-engine-siggroup.c
--- suricata-3.2/src/detect-engine-siggroup.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-siggroup.c 2017-02-15 08:54:12.000000000 +0100
@@ -321,17 +321,6 @@
return;
}
-static uint16_t SignatureGetMpmPatternLen(const Signature *s, const int list)
-{
- if (s->sm_lists[list] != NULL && s->mpm_sm != NULL &&
- SigMatchListSMBelongsTo(s, s->mpm_sm) == list)
- {
- DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx;
- return cd->content_len;
- }
- return 0;
-}
-
/**
* \brief Add a Signature to a SigGroupHead.
*
@@ -533,6 +522,7 @@
*/
void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
{
+#ifdef HAVE_MAGIC
Signature *s = NULL;
uint32_t sig = 0;
@@ -549,47 +539,11 @@
break;
}
}
-
+#endif
return;
}
/**
- * \brief Get size of the shortest mpm pattern.
- *
- * \param de_ctx detection engine ctx for the signatures
- * \param sgh sig group head to set the flag in
- * \param list sm_list to consider
- */
-uint16_t SigGroupHeadGetMinMpmSize(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, int list)
-{
- Signature *s = NULL;
- uint32_t sig = 0;
- uint16_t min = USHRT_MAX;
-
- if (sgh == NULL)
- return 0;
-
- for (sig = 0; sig < sgh->sig_cnt; sig++) {
- s = sgh->match_array[sig];
- if (s == NULL)
- continue;
-
- uint16_t mpm_content_minlen = SignatureGetMpmPatternLen(s, DETECT_SM_LIST_PMATCH);
- if (mpm_content_minlen > 0) {
- if (mpm_content_minlen < min)
- min = mpm_content_minlen;
- SCLogDebug("mpm_content_minlen %u", mpm_content_minlen);
- }
- }
-
- if (min == USHRT_MAX)
- min = 0;
- SCLogDebug("min mpm size %u", min);
- return min;
-}
-
-/**
* \brief Set the need size flag in the sgh.
*
* \param de_ctx detection engine ctx for the signatures
diff -Nru suricata-3.2/src/detect-engine-tls.c suricata-3.2.1/src/detect-engine-tls.c
--- suricata-3.2/src/detect-engine-tls.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-engine-tls.c 2017-02-15 08:54:12.000000000 +0100
@@ -156,7 +156,7 @@
SCEnter();
return PrefilterAppendTxEngine(sgh, PrefilterTxTlsIssuer,
- ALPROTO_TLS, 0, // TODO a special 'cert ready' state might be good to add
+ ALPROTO_TLS, TLS_STATE_CERT_READY,
mpm_ctx, NULL, "tls_cert_issuer");
}
@@ -215,7 +215,7 @@
const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
SSLState *ssl_state = f->alstate;
- if (ssl_state->server_connp.cert0_issuerdn == NULL)
+ if (ssl_state->server_connp.cert0_subject == NULL)
return;
const uint8_t *buffer = (const uint8_t *)ssl_state->server_connp.cert0_subject;
@@ -232,7 +232,7 @@
SCEnter();
return PrefilterAppendTxEngine(sgh, PrefilterTxTlsSubject,
- ALPROTO_TLS, 0, // TODO a special 'cert ready' state might be good to add
+ ALPROTO_TLS, TLS_STATE_CERT_READY,
mpm_ctx, NULL, "tls_cert_subject");
}
diff -Nru suricata-3.2/src/detect-filemagic.c suricata-3.2.1/src/detect-filemagic.c
--- suricata-3.2/src/detect-filemagic.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-filemagic.c 2017-02-15 08:54:12.000000000 +0100
@@ -54,6 +54,27 @@
#include "conf.h"
+#ifndef HAVE_MAGIC
+
+static int DetectFilemagicSetupNoSupport (DetectEngineCtx *de_ctx, Signature *s, char *str)
+{
+ SCLogError(SC_ERR_NO_MAGIC_SUPPORT, "no libmagic support built in, needed for filemagic keyword");
+ return -1;
+}
+
+/**
+ * \brief Registration function for keyword: filemagic
+ */
+void DetectFilemagicRegister(void)
+{
+ sigmatch_table[DETECT_FILEMAGIC].name = "filemagic";
+ sigmatch_table[DETECT_FILEMAGIC].desc = "match on the information libmagic returns about a file";
+ sigmatch_table[DETECT_FILEMAGIC].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/File-keywords#filemagic";
+ sigmatch_table[DETECT_FILEMAGIC].Setup = DetectFilemagicSetupNoSupport;
+}
+
+#else /* HAVE_MAGIC */
+
static int DetectFilemagicMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *,
uint8_t, File *, Signature *, SigMatch *);
static int DetectFilemagicSetup (DetectEngineCtx *, Signature *, char *);
@@ -89,7 +110,7 @@
*/
int FilemagicGlobalLookup(File *file)
{
- if (file == NULL || FileSize(file) == 0) {
+ if (file == NULL || FileDataSize(file) == 0) {
SCReturnInt(-1);
}
@@ -100,7 +121,7 @@
StreamingBufferGetData(file->sb,
&data, &data_len, &offset);
if (offset == 0) {
- if (FileSize(file) >= FILEMAGIC_MIN_SIZE) {
+ if (FileDataSize(file) >= FILEMAGIC_MIN_SIZE) {
file->magic = MagicGlobalLookup(data, data_len);
} else if (file->state >= FILE_STATE_CLOSED) {
file->magic = MagicGlobalLookup(data, data_len);
@@ -120,7 +141,7 @@
*/
int FilemagicThreadLookup(magic_t *ctx, File *file)
{
- if (ctx == NULL || file == NULL || FileSize(file) == 0) {
+ if (ctx == NULL || file == NULL || FileDataSize(file) == 0) {
SCReturnInt(-1);
}
@@ -131,7 +152,7 @@
StreamingBufferGetData(file->sb,
&data, &data_len, &offset);
if (offset == 0) {
- if (FileSize(file) >= FILEMAGIC_MIN_SIZE) {
+ if (FileDataSize(file) >= FILEMAGIC_MIN_SIZE) {
file->magic = MagicThreadLookup(ctx, data, data_len);
} else if (file->state >= FILE_STATE_CLOSED) {
file->magic = MagicThreadLookup(ctx, data, data_len);
@@ -453,3 +474,6 @@
UtRegisterTest("DetectFilemagicTestParse03", DetectFilemagicTestParse03);
#endif /* UNITTESTS */
}
+
+#endif /* HAVE_MAGIC */
+
diff -Nru suricata-3.2/src/detect-filemagic.h suricata-3.2.1/src/detect-filemagic.h
--- suricata-3.2/src/detect-filemagic.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-filemagic.h 2017-02-15 08:54:12.000000000 +0100
@@ -24,8 +24,8 @@
#ifndef __DETECT_FILEMAGIC_H__
#define __DETECT_FILEMAGIC_H__
+#ifdef HAVE_MAGIC
#include "util-spm-bm.h"
-#include <magic.h>
typedef struct DetectFilemagicThreadData {
magic_t ctx;
@@ -40,7 +40,8 @@
} DetectFilemagicData;
/* prototypes */
-void DetectFilemagicRegister (void);
int FilemagicGlobalLookup(File *file);
+#endif
+void DetectFilemagicRegister (void);
#endif /* __DETECT_FILEMAGIC_H__ */
diff -Nru suricata-3.2/src/detect-filesize.c suricata-3.2.1/src/detect-filesize.c
--- suricata-3.2/src/detect-filesize.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-filesize.c 2017-02-15 08:54:12.000000000 +0100
@@ -93,7 +93,7 @@
DetectFilesizeData *fsd = (DetectFilesizeData *)m->ctx;
int ret = 0;
- uint64_t file_size = FileSize(file);
+ uint64_t file_size = FileTrackedSize(file);
SCLogDebug("file size %"PRIu64", check %"PRIu64, file_size, fsd->size1);
diff -Nru suricata-3.2/src/detect.h suricata-3.2.1/src/detect.h
--- suricata-3.2/src/detect.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect.h 2017-02-15 08:54:12.000000000 +0100
@@ -838,10 +838,6 @@
/* counter for the filestore array below -- up here for cache reasons. */
uint16_t filestore_cnt;
- /* bool to hint the POSTMATCH list members about the lock status of the
- * flow. If locked this is TRUE, unlocked or no-flow: FALSE */
- uint8_t flow_locked;
-
HttpReassembledBody *hsbd;
uint64_t hsbd_start_tx_id;
uint16_t hsbd_buffers_size;
@@ -999,7 +995,9 @@
} SigTableElmt;
+#ifdef HAVE_MAGIC
#define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20)
+#endif
#define SIG_GROUP_HEAD_HAVEFILEMD5 (1 << 21)
#define SIG_GROUP_HEAD_HAVEFILESIZE (1 << 22)
#define SIG_GROUP_HEAD_HAVEFILESHA1 (1 << 23)
diff -Nru suricata-3.2/src/detect-http-header.c suricata-3.2.1/src/detect-http-header.c
--- suricata-3.2/src/detect-http-header.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-http-header.c 2017-02-15 08:54:12.000000000 +0100
@@ -724,7 +724,7 @@
goto end;
de_ctx->flags |= DE_QUIET;
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
"(msg:\"http header test\"; "
diff -Nru suricata-3.2/src/detect-ipproto.c suricata-3.2.1/src/detect-ipproto.c
--- suricata-3.2/src/detect-ipproto.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-ipproto.c 2017-02-15 08:54:12.000000000 +0100
@@ -9281,7 +9281,7 @@
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
@@ -9366,7 +9366,7 @@
goto end;
}
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
diff -Nru suricata-3.2/src/detect-parse.c suricata-3.2.1/src/detect-parse.c
--- suricata-3.2/src/detect-parse.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-parse.c 2017-02-15 08:54:12.000000000 +0100
@@ -104,11 +104,7 @@
")"
/* if enclosed in [], spaces are allowed */
-#define CONFIG_PCRE_PORT "(" \
- "[\\:A-z0-9_\\$\\!,]+"\
- "|"\
- "\\[[\\:A-z0-9_\\$\\!,\\s]+\\]"\
- ")"
+#define CONFIG_PCRE_PORT "([\\[\\]\\:A-z0-9_\\$\\!,\\s]+)"
/* format: action space(s) protocol spaces(s) src space(s) sp spaces(s) dir spaces(s) dst spaces(s) dp spaces(s) options */
#define CONFIG_PCRE "^([A-z]+)\\s+([A-z0-9\\-]+)\\s+" \
diff -Nru suricata-3.2/src/detect-tls-cert-issuer.c suricata-3.2.1/src/detect-tls-cert-issuer.c
--- suricata-3.2/src/detect-tls-cert-issuer.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-tls-cert-issuer.c 2017-02-15 08:54:12.000000000 +0100
@@ -63,6 +63,7 @@
{
sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].name = "tls_cert_issuer";
sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].desc = "content modifier to match specifically and only on the TLS cert issuer buffer";
+ sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].url = DOC_URL DOC_VERSION "/rules/tls-keywords.html#tls-cert-issuer";
sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].Match = NULL;
sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_TLS_CERT_ISSUER].Setup = DetectTlsIssuerSetup;
@@ -387,7 +388,7 @@
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert tls any any -> any any "
diff -Nru suricata-3.2/src/detect-tls-cert-subject.c suricata-3.2.1/src/detect-tls-cert-subject.c
--- suricata-3.2/src/detect-tls-cert-subject.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-tls-cert-subject.c 2017-02-15 08:54:12.000000000 +0100
@@ -63,6 +63,7 @@
{
sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].name = "tls_cert_subject";
sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].desc = "content modifier to match specifically and only on the TLS cert subject buffer";
+ sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].url = DOC_URL DOC_VERSION "/rules/tls-keywords.html#tls-cert-subject";
sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].Match = NULL;
sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_TLS_CERT_SUBJECT].Setup = DetectTlsSubjectSetup;
@@ -387,7 +388,7 @@
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert tls any any -> any any "
diff -Nru suricata-3.2/src/detect-tls-sni.c suricata-3.2.1/src/detect-tls-sni.c
--- suricata-3.2/src/detect-tls-sni.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-tls-sni.c 2017-02-15 08:54:12.000000000 +0100
@@ -63,6 +63,7 @@
{
sigmatch_table[DETECT_AL_TLS_SNI].name = "tls_sni";
sigmatch_table[DETECT_AL_TLS_SNI].desc = "content modifier to match specifically and only on the TLS SNI buffer";
+ sigmatch_table[DETECT_AL_TLS_SNI].url = DOC_URL DOC_VERSION "/rules/tls-keywords.html#tls-sni";
sigmatch_table[DETECT_AL_TLS_SNI].Match = NULL;
sigmatch_table[DETECT_AL_TLS_SNI].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_TLS_SNI].Setup = DetectTlsSniSetup;
@@ -156,7 +157,7 @@
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert tls any any -> any any "
@@ -248,7 +249,7 @@
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
- de_ctx->mpm_matcher = DEFAULT_MPM;
+ de_ctx->mpm_matcher = mpm_default_matcher;
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx, "alert tls any any -> any any "
diff -Nru suricata-3.2/src/detect-xbits.c suricata-3.2.1/src/detect-xbits.c
--- suricata-3.2/src/detect-xbits.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-xbits.c 2017-02-15 08:54:12.000000000 +0100
@@ -66,7 +66,7 @@
{
sigmatch_table[DETECT_XBITS].name = "xbits";
sigmatch_table[DETECT_XBITS].desc = "operate on bits";
-// sigmatch_table[DETECT_XBITS].url = DOC_URL DOC_VERSION "/rules/flow-keywords.html#flowbits";
+ sigmatch_table[DETECT_XBITS].url = DOC_URL DOC_VERSION "/rules/xbits.html";
sigmatch_table[DETECT_XBITS].Match = DetectXbitMatch;
sigmatch_table[DETECT_XBITS].Setup = DetectXbitSetup;
sigmatch_table[DETECT_XBITS].Free = DetectXbitFree;
@@ -180,10 +180,16 @@
return 0;
}
-int DetectXbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
+/** \internal
+ * \brief parse xbits rule options
+ * \retval 0 ok
+ * \retval -1 bad
+ * \param[out] cdout return DetectXbitsData structure or NULL if noalert
+ */
+static int DetectXbitParse(DetectEngineCtx *de_ctx,
+ const char *rawstr, DetectXbitsData **cdout)
{
DetectXbitsData *cd = NULL;
- SigMatch *sm = NULL;
uint8_t fb_cmd = 0;
uint8_t hb_dir = 0;
#define MAX_SUBSTRINGS 30
@@ -192,7 +198,7 @@
char fb_cmd_str[16] = "", fb_name[256] = "";
char hb_dir_str[16] = "";
enum VarTypes var_type = VAR_TYPE_NOT_SET;
- int expire = 30;
+ int expire = DETECT_XBITS_EXPIRE_DEFAULT;
ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
if (ret != 2 && ret != 3 && ret != 4 && ret != 5) {
@@ -210,13 +216,13 @@
res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, fb_name, sizeof(fb_name));
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
- goto error;
+ return -1;
}
if (ret >= 4) {
res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, hb_dir_str, sizeof(hb_dir_str));
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
- goto error;
+ return -1;
}
SCLogDebug("hb_dir_str %s", hb_dir_str);
if (strlen(hb_dir_str) > 0) {
@@ -231,7 +237,7 @@
var_type = VAR_TYPE_IPPAIR_BIT;
} else {
// TODO
- goto error;
+ return -1;
}
}
@@ -240,10 +246,19 @@
res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, expire_str, sizeof(expire_str));
if (res < 0) {
SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
- goto error;
+ return -1;
}
SCLogDebug("expire_str %s", expire_str);
expire = atoi(expire_str);
+ if (expire < 0) {
+ SCLogError(SC_ERR_INVALID_VALUE, "expire must be positive. "
+ "Got %d (\"%s\")", expire, expire_str);
+ return -1;
+ }
+ if (expire == 0) {
+ SCLogError(SC_ERR_INVALID_VALUE, "expire must be bigger than 0");
+ return -1;
+ }
SCLogDebug("expire %d", expire);
}
}
@@ -262,16 +277,18 @@
} else if (strcmp(fb_cmd_str,"toggle") == 0) {
fb_cmd = DETECT_XBITS_CMD_TOGGLE;
} else {
- SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str);
- goto error;
+ SCLogError(SC_ERR_UNKNOWN_VALUE, "xbits action \"%s\" is not supported.", fb_cmd_str);
+ return -1;
}
switch (fb_cmd) {
- case DETECT_XBITS_CMD_NOALERT:
+ case DETECT_XBITS_CMD_NOALERT: {
if (strlen(fb_name) != 0)
- goto error;
- s->flags |= SIG_FLAG_NOALERT;
+ return -1;
+ /* return ok, cd is NULL. Flag sig. */
+ *cdout = NULL;
return 0;
+ }
case DETECT_XBITS_CMD_ISNOTSET:
case DETECT_XBITS_CMD_ISSET:
case DETECT_XBITS_CMD_SET:
@@ -279,13 +296,13 @@
case DETECT_XBITS_CMD_TOGGLE:
default:
if (strlen(fb_name) == 0)
- goto error;
+ return -1;
break;
}
cd = SCMalloc(sizeof(DetectXbitsData));
if (unlikely(cd == NULL))
- goto error;
+ return -1;
cd->idx = VariableNameGetIdx(de_ctx, fb_name, var_type);
cd->cmd = fb_cmd;
@@ -296,6 +313,24 @@
SCLogDebug("idx %" PRIu32 ", cmd %s, name %s",
cd->idx, fb_cmd_str, strlen(fb_name) ? fb_name : "(none)");
+ *cdout = cd;
+ return 0;
+}
+
+int DetectXbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr)
+{
+ SigMatch *sm = NULL;
+ DetectXbitsData *cd = NULL;
+
+ int result = DetectXbitParse(de_ctx, rawstr, &cd);
+ if (result < 0) {
+ return -1;
+ /* noalert doesn't use a cd/sm struct. It flags the sig. We're done. */
+ } else if (result == 0 && cd == NULL) {
+ s->flags |= SIG_FLAG_NOALERT;
+ return 0;
+ }
+
/* Okay so far so good, lets get this into a SigMatch
* and put it in the Signature. */
sm = SigMatchAlloc();
@@ -305,7 +340,7 @@
sm->type = DETECT_XBITS;
sm->ctx = (void *)cd;
- switch (fb_cmd) {
+ switch (cd->cmd) {
/* case DETECT_XBITS_CMD_NOALERT can't happen here */
case DETECT_XBITS_CMD_ISNOTSET:
@@ -327,8 +362,6 @@
error:
if (cd != NULL)
SCFree(cd);
- if (sm != NULL)
- SCFree(sm);
return -1;
}
@@ -361,11 +394,59 @@
StorageCleanup();
}
+
+static int XBitsTestParse01(void)
+{
+ DetectEngineCtx *de_ctx = NULL;
+ de_ctx = DetectEngineCtxInit();
+ FAIL_IF_NULL(de_ctx);
+ de_ctx->flags |= DE_QUIET;
+ DetectXbitsData *cd = NULL;
+
+#define BAD_INPUT(str) \
+ FAIL_IF_NOT(DetectXbitParse(de_ctx, (str), &cd) == -1);
+
+ BAD_INPUT("alert");
+ BAD_INPUT("n0alert");
+ BAD_INPUT("nOalert");
+ BAD_INPUT("set,abc,track nonsense, expire 3600");
+ BAD_INPUT("set,abc,track ip_source, expire 3600");
+ BAD_INPUT("set,abc,track ip_src, expire -1");
+ BAD_INPUT("set,abc,track ip_src, expire 0");
+
+#undef BAD_INPUT
+
+#define GOOD_INPUT(str, command, trk, typ, exp) \
+ FAIL_IF_NOT(DetectXbitParse(de_ctx, (str), &cd) == 0); \
+ FAIL_IF_NULL(cd); \
+ FAIL_IF_NOT(cd->cmd == (command)); \
+ FAIL_IF_NOT(cd->tracker == (trk)); \
+ FAIL_IF_NOT(cd->type == (typ)); \
+ FAIL_IF_NOT(cd->expire == (exp)); \
+ DetectXbitFree(cd); \
+ cd = NULL;
+
+ GOOD_INPUT("set,abc,track ip_pair",
+ DETECT_XBITS_CMD_SET,
+ DETECT_XBITS_TRACK_IPPAIR, VAR_TYPE_IPPAIR_BIT,
+ DETECT_XBITS_EXPIRE_DEFAULT);
+ GOOD_INPUT("set,abc,track ip_pair, expire 3600",
+ DETECT_XBITS_CMD_SET,
+ DETECT_XBITS_TRACK_IPPAIR, VAR_TYPE_IPPAIR_BIT,
+ 3600);
+ GOOD_INPUT("set,abc,track ip_src, expire 1234",
+ DETECT_XBITS_CMD_SET,
+ DETECT_XBITS_TRACK_IPSRC, VAR_TYPE_HOST_BIT,
+ 1234);
+
+#undef GOOD_INPUT
+
+ DetectEngineCtxFree(de_ctx);
+ PASS;
+}
+
/**
- * \test HostBitsTestSig01 is a test for a valid noalert flowbits option
- *
- * \retval 1 on succces
- * \retval 0 on failure
+ * \test
*/
static int XBitsTestSig01(void)
@@ -376,13 +457,11 @@
"\r\n";
uint16_t buflen = strlen((char *)buf);
Packet *p = SCMalloc(SIZE_OF_PACKET);
- if (unlikely(p == NULL))
- return 0;
+ FAIL_IF_NULL(p);
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
DetectEngineCtx *de_ctx = NULL;
- int result = 0;
memset(&th_v, 0, sizeof(th_v));
memset(p, 0, SIZE_OF_PACKET);
@@ -395,46 +474,23 @@
XBitsTestSetup();
de_ctx = DetectEngineCtxInit();
-
- if (de_ctx == NULL) {
- printf("bad de_ctx: ");
- goto end;
- }
-
+ FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx,
"alert ip any any -> any any (xbits:set,abc,track ip_pair; content:\"GET \"; sid:1;)");
- if (s == NULL) {
- printf("bad sig: ");
- goto end;
- }
+ FAIL_IF_NULL(s);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
-
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
-
- result = 1;
-
-end:
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- }
-
- if (det_ctx != NULL) {
- DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
- }
-
- if (de_ctx != NULL) {
- DetectEngineCtxFree(de_ctx);
- }
-
+ DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
+ DetectEngineCtxFree(de_ctx);
XBitsTestShutdown();
-
SCFree(p);
- return result;
+ StatsThreadCleanup(&th_v);
+ StatsReleaseResources();
+ PASS;
}
/**
@@ -447,67 +503,33 @@
static int XBitsTestSig02(void)
{
Signature *s = NULL;
- ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
- int result = 0;
- int error_count = 0;
-
- memset(&th_v, 0, sizeof(th_v));
-
de_ctx = DetectEngineCtxInit();
- if (de_ctx == NULL) {
- goto end;
- }
-
+ FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;
s = DetectEngineAppendSig(de_ctx,
"alert ip any any -> any any (xbits:isset,abc,track ip_src; content:\"GET \"; sid:1;)");
- if (s == NULL) {
- error_count++;
- }
+ FAIL_IF_NULL(s);
s = DetectEngineAppendSig(de_ctx,
"alert ip any any -> any any (xbits:isnotset,abc,track ip_dst; content:\"GET \"; sid:2;)");
- if (s == NULL) {
- error_count++;
- }
+ FAIL_IF_NULL(s);
s = DetectEngineAppendSig(de_ctx,
"alert ip any any -> any any (xbits:set,abc,track ip_pair; content:\"GET \"; sid:3;)");
- if (s == NULL) {
- error_count++;
- }
+ FAIL_IF_NULL(s);
s = DetectEngineAppendSig(de_ctx,
"alert ip any any -> any any (xbits:unset,abc,track ip_src; content:\"GET \"; sid:4;)");
- if (s == NULL) {
- error_count++;
- }
+ FAIL_IF_NULL(s);
s = DetectEngineAppendSig(de_ctx,
"alert ip any any -> any any (xbits:toggle,abc,track ip_dst; content:\"GET \"; sid:5;)");
- if (s == NULL) {
- error_count++;
- }
+ FAIL_IF_NULL(s);
- if (error_count != 0)
- goto end;
-
- result = 1;
-
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
- return result;
-end:
- if (de_ctx != NULL) {
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
- DetectEngineCtxFree(de_ctx);
- }
-
- return result;
+ PASS;
}
#endif /* UNITTESTS */
@@ -518,6 +540,7 @@
void XBitsRegisterTests(void)
{
#ifdef UNITTESTS
+ UtRegisterTest("XBitsTestParse01", XBitsTestParse01);
UtRegisterTest("XBitsTestSig01", XBitsTestSig01);
UtRegisterTest("XBitsTestSig02", XBitsTestSig02);
#endif /* UNITTESTS */
diff -Nru suricata-3.2/src/detect-xbits.h suricata-3.2.1/src/detect-xbits.h
--- suricata-3.2/src/detect-xbits.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/detect-xbits.h 2017-02-15 08:54:12.000000000 +0100
@@ -37,6 +37,8 @@
#define DETECT_XBITS_TRACK_IPPAIR 2
#define DETECT_XBITS_TRACK_FLOW 3
+#define DETECT_XBITS_EXPIRE_DEFAULT 30
+
typedef struct DetectXbitsData_ {
uint16_t idx;
uint8_t cmd;
diff -Nru suricata-3.2/src/flow.c suricata-3.2.1/src/flow.c
--- suricata-3.2/src/flow.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/flow.c 2017-02-15 08:54:12.000000000 +0100
@@ -157,6 +157,30 @@
return;
}
+/** \brief Set flag to indicate that flow has alerts
+ *
+ * \param f flow
+ */
+void FlowSetHasAlertsFlag(Flow *f)
+{
+ f->flags |= FLOW_HAS_ALERTS;
+}
+
+/** \brief Check if flow has alerts
+ *
+ * \param f flow
+ * \retval 1 has alerts
+ * \retval 0 has not alerts
+ */
+int FlowHasAlerts(const Flow *f)
+{
+ if (f->flags & FLOW_HAS_ALERTS) {
+ return 1;
+ }
+
+ return 0;
+}
+
/**
* \brief determine the direction of the packet compared to the flow
* \retval 0 to_server
diff -Nru suricata-3.2/src/flow.h suricata-3.2.1/src/flow.h
--- suricata-3.2/src/flow.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/flow.h 2017-02-15 08:54:12.000000000 +0100
@@ -72,7 +72,8 @@
/** packet to client direction has been logged in drop file (only in IPS mode) */
#define FLOW_TOCLIENT_DROP_LOGGED BIT_U32(11)
-// vacancy bit 12
+/** flow has alerts */
+#define FLOW_HAS_ALERTS BIT_U32(12)
/** Pattern matcher alproto detection done */
#define FLOW_TS_PM_ALPROTO_DETECT_DONE BIT_U32(13)
@@ -458,6 +459,8 @@
void FlowPrintQueueInfo (void);
void FlowShutdown(void);
void FlowSetIPOnlyFlag(Flow *, int);
+void FlowSetHasAlertsFlag(Flow *);
+int FlowHasAlerts(const Flow *);
void FlowRegisterTests (void);
int FlowSetProtoTimeout(uint8_t ,uint32_t ,uint32_t ,uint32_t);
diff -Nru suricata-3.2/src/host-bit.c suricata-3.2.1/src/host-bit.c
--- suricata-3.2/src/host-bit.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/host-bit.c 2017-02-15 08:54:12.000000000 +0100
@@ -123,6 +123,7 @@
GenericVar *gv = HostGetStorageById(h, host_bit_id);
if (gv) {
GenericVarRemove(&gv, (GenericVar *)fb);
+ XBitFree(fb);
HostSetStorageById(h, host_bit_id, gv);
}
}
diff -Nru suricata-3.2/src/log-dnslog.c suricata-3.2.1/src/log-dnslog.c
--- suricata-3.2/src/log-dnslog.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/log-dnslog.c 2017-02-15 08:54:12.000000000 +0100
@@ -138,11 +138,11 @@
" [**] %s [**] TTL %u [**] ", record, entry->ttl);
uint8_t *ptr = (uint8_t *)((uint8_t *)entry + sizeof(DNSAnswerEntry) + entry->fqdn_len);
- if (entry->type == DNS_RECORD_TYPE_A) {
+ if (entry->type == DNS_RECORD_TYPE_A && entry->data_len == 4) {
char a[16] = "";
PrintInet(AF_INET, (const void *)ptr, a, sizeof(a));
MemBufferWriteString(aft->buffer, "%s", a);
- } else if (entry->type == DNS_RECORD_TYPE_AAAA) {
+ } else if (entry->type == DNS_RECORD_TYPE_AAAA && entry->data_len == 16) {
char a[46];
PrintInet(AF_INET6, (const void *)ptr, a, sizeof(a));
MemBufferWriteString(aft->buffer, "%s", a);
@@ -165,8 +165,8 @@
SCMutexUnlock(&hlog->file_ctx->fp_mutex);
}
-static int LogDnsLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f,
- void *state, void *tx, uint64_t tx_id)
+static int LogDnsLogger(ThreadVars *tv, void *data, const Packet *p,
+ Flow *f, void *state, void *tx, uint64_t tx_id, uint8_t direction)
{
LogDnsLogThread *aft = (LogDnsLogThread *)data;
DNSTransaction *dns_tx = (DNSTransaction *)tx;
@@ -214,24 +214,26 @@
dp = p->sp;
}
- DNSQueryEntry *query = NULL;
- TAILQ_FOREACH(query, &dns_tx->query_list, next) {
- LogQuery(aft, timebuf, dstip, srcip, dp, sp, dns_tx, query);
- }
-
- if (dns_tx->rcode)
- LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, NULL);
- if (dns_tx->recursion_desired)
- LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, NULL);
-
- DNSAnswerEntry *entry = NULL;
- TAILQ_FOREACH(entry, &dns_tx->answer_list, next) {
- LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, entry);
- }
+ if (direction == STREAM_TOSERVER) {
+ DNSQueryEntry *query = NULL;
+ TAILQ_FOREACH(query, &dns_tx->query_list, next) {
+ LogQuery(aft, timebuf, dstip, srcip, dp, sp, dns_tx, query);
+ }
+ } else if (direction == STREAM_TOCLIENT) {
+ if (dns_tx->rcode)
+ LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, NULL);
+ if (dns_tx->recursion_desired)
+ LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, NULL);
+
+ DNSAnswerEntry *entry = NULL;
+ TAILQ_FOREACH(entry, &dns_tx->answer_list, next) {
+ LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, entry);
+ }
- entry = NULL;
- TAILQ_FOREACH(entry, &dns_tx->authority_list, next) {
- LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, entry);
+ entry = NULL;
+ TAILQ_FOREACH(entry, &dns_tx->authority_list, next) {
+ LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, entry);
+ }
}
aft->dns_cnt++;
@@ -239,6 +241,18 @@
return 0;
}
+static int LogDnsRequestLogger(ThreadVars *tv, void *data, const Packet *p,
+ Flow *f, void *state, void *tx, uint64_t tx_id)
+{
+ return LogDnsLogger(tv, data, p, f, state, tx, tx_id, STREAM_TOSERVER);
+}
+
+static int LogDnsResponseLogger(ThreadVars *tv, void *data, const Packet *p,
+ Flow *f, void *state, void *tx, uint64_t tx_id)
+{
+ return LogDnsLogger(tv, data, p, f, state, tx, tx_id, STREAM_TOCLIENT);
+}
+
static TmEcode LogDnsLogThreadInit(ThreadVars *t, void *initdata, void **data)
{
LogDnsLogThread *aft = SCMalloc(sizeof(LogDnsLogThread));
@@ -346,9 +360,15 @@
void LogDnsLogRegister (void)
{
- OutputRegisterTxModule(LOGGER_DNS, MODULE_NAME, "dns-log", LogDnsLogInitCtx,
- ALPROTO_DNS, LogDnsLogger, LogDnsLogThreadInit, LogDnsLogThreadDeinit,
- LogDnsLogExitPrintStats);
+ /* Request logger. */
+ OutputRegisterTxModuleWithProgress(LOGGER_DNS, MODULE_NAME, "dns-log",
+ LogDnsLogInitCtx, ALPROTO_DNS, LogDnsRequestLogger, 0, 1,
+ LogDnsLogThreadInit, LogDnsLogThreadDeinit, LogDnsLogExitPrintStats);
+
+ /* Response logger. */
+ OutputRegisterTxModuleWithProgress(LOGGER_DNS, MODULE_NAME, "dns-log",
+ LogDnsLogInitCtx, ALPROTO_DNS, LogDnsResponseLogger, 1, 1,
+ LogDnsLogThreadInit, LogDnsLogThreadDeinit, LogDnsLogExitPrintStats);
/* enable the logger for the app layer */
SCLogDebug("registered %s", MODULE_NAME);
diff -Nru suricata-3.2/src/log-file.c suricata-3.2.1/src/log-file.c
--- suricata-3.2/src/log-file.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/log-file.c 2017-02-15 08:54:12.000000000 +0100
@@ -269,7 +269,7 @@
fprintf(fp, "\"filename\": \"");
PrintRawJsonFp(fp, ff->name, ff->name_len);
fprintf(fp, "\", ");
-
+#ifdef HAVE_MAGIC
fprintf(fp, "\"magic\": \"");
if (ff->magic) {
PrintRawJsonFp(fp, (uint8_t *)ff->magic, strlen(ff->magic));
@@ -277,7 +277,7 @@
fprintf(fp, "unknown");
}
fprintf(fp, "\", ");
-
+#endif
switch (ff->state) {
case FILE_STATE_CLOSED:
fprintf(fp, "\"state\": \"CLOSED\", ");
@@ -319,7 +319,7 @@
break;
}
fprintf(fp, "\"stored\": %s, ", ff->flags & FILE_STORED ? "true" : "false");
- fprintf(fp, "\"size\": %"PRIu64" ", FileSize(ff));
+ fprintf(fp, "\"size\": %"PRIu64" ", FileTrackedSize(ff));
fprintf(fp, "}\n");
fflush(fp);
SCMutexUnlock(&aft->file_ctx->fp_mutex);
diff -Nru suricata-3.2/src/log-filestore.c suricata-3.2.1/src/log-filestore.c
--- suricata-3.2/src/log-filestore.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/log-filestore.c 2017-02-15 08:54:12.000000000 +0100
@@ -247,9 +247,10 @@
snprintf(metafilename, sizeof(metafilename), "%s.meta", filename);
FILE *fp = fopen(metafilename, "a");
if (fp != NULL) {
+#ifdef HAVE_MAGIC
fprintf(fp, "MAGIC: %s\n",
ff->magic ? ff->magic : "<unknown>");
-
+#endif
switch (ff->state) {
case FILE_STATE_CLOSED:
fprintf(fp, "STATE: CLOSED\n");
@@ -290,7 +291,7 @@
fprintf(fp, "STATE: UNKNOWN\n");
break;
}
- fprintf(fp, "SIZE: %"PRIu64"\n", FileSize(ff));
+ fprintf(fp, "SIZE: %"PRIu64"\n", FileTrackedSize(ff));
fclose(fp);
} else {
diff -Nru suricata-3.2/src/log-pcap.c suricata-3.2.1/src/log-pcap.c
--- suricata-3.2/src/log-pcap.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/log-pcap.c 2017-02-15 08:54:12.000000000 +0100
@@ -82,6 +82,8 @@
#define HONOR_PASS_RULES_DISABLED 0
#define HONOR_PASS_RULES_ENABLED 1
+#define PCAP_SNAPLEN 262144
+
SC_ATOMIC_DECLARE(uint32_t, thread_cnt);
typedef struct PcapFileName_ {
@@ -317,7 +319,7 @@
if (pl->pcap_dead_handle == NULL) {
if ((pl->pcap_dead_handle = pcap_open_dead(p->datalink,
- -1)) == NULL) {
+ PCAP_SNAPLEN)) == NULL) {
SCLogDebug("Error opening dead pcap handle");
return TM_ECODE_FAILED;
}
@@ -669,6 +671,7 @@
strerror(errno));
}
TAILQ_REMOVE(&pl->pcap_file_list, pf, next);
+ PcapFileNameFree(pf);
pf = TAILQ_FIRST(&pl->pcap_file_list);
pl->file_cnt--;
}
@@ -959,7 +962,7 @@
timestamp_pattern, pcre_erroffset, pcre_errbuf);
}
pcre_timestamp_extra = pcre_study(pcre_timestamp_code, 0, &pcre_errbuf);
- if (pcre_timestamp_extra == NULL) {
+ if (pcre_errbuf != NULL) {
FatalError(SC_ERR_PCRE_STUDY, "Fail to study pcre: %s", pcre_errbuf);
}
diff -Nru suricata-3.2/src/log-tlsstore.c suricata-3.2.1/src/log-tlsstore.c
--- suricata-3.2/src/log-tlsstore.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/log-tlsstore.c 2017-02-15 08:54:12.000000000 +0100
@@ -166,7 +166,6 @@
goto end_fwrite_fp;
}
fclose(fp);
- SCFree(aft->enc_buf);
//Logging certificate informations
memcpy(filename + (strlen(filename) - 3), "meta", 4);
@@ -223,7 +222,6 @@
end_fwrite_fp:
fclose(fp);
- SCFree(aft->enc_buf);
if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) {
SCLogWarning(SC_ERR_FWRITE, "Unable to write certificate");
logging_dir_not_writable++;
@@ -338,6 +336,9 @@
return TM_ECODE_OK;
}
+ if (aft->enc_buf != NULL)
+ SCFree(aft->enc_buf);
+
/* clear memory */
memset(aft, 0, sizeof(LogTlsStoreLogThread));
diff -Nru suricata-3.2/src/Makefile.am suricata-3.2.1/src/Makefile.am
--- suricata-3.2/src/Makefile.am 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/Makefile.am 2017-02-15 08:54:12.000000000 +0100
@@ -46,6 +46,7 @@
counters.c counters.h \
data-queue.c data-queue.h \
decode.c decode.h \
+decode-afl.c \
decode-erspan.c decode-erspan.h \
decode-ethernet.c decode-ethernet.h \
decode-events.c decode-events.h \
diff -Nru suricata-3.2/src/Makefile.in suricata-3.2.1/src/Makefile.in
--- suricata-3.2/src/Makefile.in 2016-11-29 18:17:05.000000000 +0100
+++ suricata-3.2.1/src/Makefile.in 2017-02-15 08:54:31.000000000 +0100
@@ -127,20 +127,20 @@
app-layer-ssh.$(OBJEXT) app-layer-ssl.$(OBJEXT) \
app-layer-tls-handshake.$(OBJEXT) conf.$(OBJEXT) \
conf-yaml-loader.$(OBJEXT) counters.$(OBJEXT) \
- data-queue.$(OBJEXT) decode.$(OBJEXT) decode-erspan.$(OBJEXT) \
- decode-ethernet.$(OBJEXT) decode-events.$(OBJEXT) \
- decode-gre.$(OBJEXT) decode-icmpv4.$(OBJEXT) \
- decode-icmpv6.$(OBJEXT) decode-ipv4.$(OBJEXT) \
- decode-ipv6.$(OBJEXT) decode-null.$(OBJEXT) \
- decode-ppp.$(OBJEXT) decode-pppoe.$(OBJEXT) \
- decode-raw.$(OBJEXT) decode-sctp.$(OBJEXT) \
- decode-sll.$(OBJEXT) decode-tcp.$(OBJEXT) \
- decode-teredo.$(OBJEXT) decode-udp.$(OBJEXT) \
- decode-vlan.$(OBJEXT) decode-mpls.$(OBJEXT) \
- decode-template.$(OBJEXT) defrag-config.$(OBJEXT) \
- defrag.$(OBJEXT) defrag-hash.$(OBJEXT) defrag-queue.$(OBJEXT) \
- defrag-timeout.$(OBJEXT) detect-ack.$(OBJEXT) \
- detect-app-layer-event.$(OBJEXT) \
+ data-queue.$(OBJEXT) decode.$(OBJEXT) decode-afl.$(OBJEXT) \
+ decode-erspan.$(OBJEXT) decode-ethernet.$(OBJEXT) \
+ decode-events.$(OBJEXT) decode-gre.$(OBJEXT) \
+ decode-icmpv4.$(OBJEXT) decode-icmpv6.$(OBJEXT) \
+ decode-ipv4.$(OBJEXT) decode-ipv6.$(OBJEXT) \
+ decode-null.$(OBJEXT) decode-ppp.$(OBJEXT) \
+ decode-pppoe.$(OBJEXT) decode-raw.$(OBJEXT) \
+ decode-sctp.$(OBJEXT) decode-sll.$(OBJEXT) \
+ decode-tcp.$(OBJEXT) decode-teredo.$(OBJEXT) \
+ decode-udp.$(OBJEXT) decode-vlan.$(OBJEXT) \
+ decode-mpls.$(OBJEXT) decode-template.$(OBJEXT) \
+ defrag-config.$(OBJEXT) defrag.$(OBJEXT) defrag-hash.$(OBJEXT) \
+ defrag-queue.$(OBJEXT) defrag-timeout.$(OBJEXT) \
+ detect-ack.$(OBJEXT) detect-app-layer-event.$(OBJEXT) \
detect-app-layer-protocol.$(OBJEXT) detect-asn1.$(OBJEXT) \
detect-base64-data.$(OBJEXT) detect-base64-decode.$(OBJEXT) \
detect-byte-extract.$(OBJEXT) detect-bytejump.$(OBJEXT) \
@@ -634,6 +634,7 @@
counters.c counters.h \
data-queue.c data-queue.h \
decode.c decode.h \
+decode-afl.c \
decode-erspan.c decode-erspan.h \
decode-ethernet.c decode-ethernet.h \
decode-events.c decode-events.h \
@@ -1197,6 +1198,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/counters.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data-queue.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode-afl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode-erspan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode-ethernet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode-events.Po@am__quote@
diff -Nru suricata-3.2/src/output-file.c suricata-3.2.1/src/output-file.c
--- suricata-3.2/src/output-file.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/output-file.c 2017-02-15 08:54:12.000000000 +0100
@@ -147,11 +147,11 @@
ff->state == FILE_STATE_ERROR)
{
int file_logged = 0;
-
+#ifdef HAVE_MAGIC
if (FileForceMagic() && ff->magic == NULL) {
FilemagicGlobalLookup(ff);
}
-
+#endif
logger = list;
store = op_thread_data->store;
while (logger && store) {
diff -Nru suricata-3.2/src/output-filedata.c suricata-3.2.1/src/output-filedata.c
--- suricata-3.2/src/output-filedata.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/output-filedata.c 2017-02-15 08:54:12.000000000 +0100
@@ -165,10 +165,11 @@
if (ffc != NULL) {
File *ff;
for (ff = ffc->head; ff != NULL; ff = ff->next) {
+#ifdef HAVE_MAGIC
if (FileForceMagic() && ff->magic == NULL) {
FilemagicGlobalLookup(ff);
}
-
+#endif
SCLogDebug("ff %p", ff);
if (ff->flags & FILE_STORED) {
SCLogDebug("stored flag set");
@@ -182,7 +183,7 @@
/* if we have no data chunks left to log, we should still
* close the logger(s) */
- if (FileSize(ff) == ff->content_stored &&
+ if (FileDataSize(ff) == ff->content_stored &&
(file_trunc || file_close)) {
CallLoggers(tv, store, p, ff, NULL, 0, OUTPUT_FILEDATA_FLAG_CLOSE);
ff->flags |= FILE_STORED;
diff -Nru suricata-3.2/src/output-json-dns.c suricata-3.2.1/src/output-json-dns.c
--- suricata-3.2/src/output-json-dns.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/output-json-dns.c 2017-02-15 08:54:12.000000000 +0100
@@ -479,11 +479,11 @@
json_object_set_new(js, "ttl", json_integer(entry->ttl));
uint8_t *ptr = (uint8_t *)((uint8_t *)entry + sizeof(DNSAnswerEntry)+ entry->fqdn_len);
- if (entry->type == DNS_RECORD_TYPE_A) {
+ if (entry->type == DNS_RECORD_TYPE_A && entry->data_len == 4) {
char a[16] = "";
PrintInet(AF_INET, (const void *)ptr, a, sizeof(a));
json_object_set_new(js, "rdata", json_string(a));
- } else if (entry->type == DNS_RECORD_TYPE_AAAA) {
+ } else if (entry->type == DNS_RECORD_TYPE_AAAA && entry->data_len == 16) {
char a[46] = "";
PrintInet(AF_INET6, (const void *)ptr, a, sizeof(a));
json_object_set_new(js, "rdata", json_string(a));
diff -Nru suricata-3.2/src/output-json-file.c suricata-3.2.1/src/output-json-file.c
--- suricata-3.2/src/output-json-file.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/output-json-file.c 2017-02-15 08:54:12.000000000 +0100
@@ -119,8 +119,10 @@
json_object_set_new(fjs, "filename", json_string(s));
if (s != NULL)
SCFree(s);
+#ifdef HAVE_MAGIC
if (ff->magic)
json_object_set_new(fjs, "magic", json_string((char *)ff->magic));
+#endif
switch (ff->state) {
case FILE_STATE_CLOSED:
json_object_set_new(fjs, "state", json_string("CLOSED"));
@@ -169,7 +171,7 @@
if (ff->flags & FILE_STORED) {
json_object_set_new(fjs, "file_id", json_integer(ff->file_id));
}
- json_object_set_new(fjs, "size", json_integer(FileSize(ff)));
+ json_object_set_new(fjs, "size", json_integer(FileTrackedSize(ff)));
json_object_set_new(fjs, "tx_id", json_integer(ff->txid));
/* originally just 'file', but due to bug 1127 naming it fileinfo */
diff -Nru suricata-3.2/src/output-json-flow.c suricata-3.2.1/src/output-json-flow.c
--- suricata-3.2/src/output-json-flow.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/output-json-flow.c 2017-02-15 08:54:12.000000000 +0100
@@ -261,6 +261,8 @@
json_object_set_new(hjs, "reason",
json_string(reason));
+ json_object_set_new(hjs, "alerted", json_boolean(FlowHasAlerts(f)));
+
json_object_set_new(js, "flow", hjs);
diff -Nru suricata-3.2/src/output-json-template.c suricata-3.2.1/src/output-json-template.c
--- suricata-3.2/src/output-json-template.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/output-json-template.c 2017-02-15 08:54:12.000000000 +0100
@@ -110,9 +110,6 @@
return TM_ECODE_OK;
error:
- if (templatejs != NULL) {
- json_decref(templatejs);
- }
json_decref(js);
return TM_ECODE_FAILED;
}
diff -Nru suricata-3.2/src/output-tx.c suricata-3.2.1/src/output-tx.c
--- suricata-3.2/src/output-tx.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/output-tx.c 2017-02-15 08:54:12.000000000 +0100
@@ -163,10 +163,17 @@
uint64_t total_txs = AppLayerParserGetTxCnt(p->proto, alproto, alstate);
uint64_t tx_id = AppLayerParserGetTransactionLogId(f->alparser);
+ uint64_t max_id = tx_id;
+ int logged = 0;
+ int gap = 0;
for (; tx_id < total_txs; tx_id++)
{
- int logger_not_logged = 0;
+ /* Track the number of loggers, of the eligible loggers that
+ * actually logged this transaction. They all must have logged
+ * before the transaction is considered logged. */
+ int number_of_loggers = 0;
+ int loggers_that_logged = 0;
void *tx = AppLayerParserGetTx(p->proto, alproto, alstate, tx_id);
if (tx == NULL) {
@@ -195,10 +202,12 @@
if (logger->alproto == alproto) {
SCLogDebug("alproto match, logging tx_id %"PRIu64, tx_id);
+ number_of_loggers++;
+
if (AppLayerParserGetTxLogged(p->proto, alproto, alstate, tx,
logger->id)) {
SCLogDebug("logger has already logged this transaction");
-
+ loggers_that_logged++;
goto next;
}
@@ -208,30 +217,30 @@
int r = logger->LogCondition(tv, p, alstate, tx, tx_id);
if (r == FALSE) {
SCLogDebug("conditions not met, not logging");
- logger_not_logged = 1;
goto next;
}
} else {
if (tx_progress_tc < logger->tc_log_progress) {
SCLogDebug("progress not far enough, not logging");
- logger_not_logged = 1;
goto next;
}
if (tx_progress_ts < logger->ts_log_progress) {
SCLogDebug("progress not far enough, not logging");
- logger_not_logged = 1;
goto next;
}
}
}
+ SCLogDebug("Logging tx_id %"PRIu64" to logger %d", tx_id,
+ logger->logger_id);
PACKET_PROFILING_LOGGER_START(p, logger->logger_id);
logger->LogFunc(tv, store->thread_data, p, f, alstate, tx, tx_id);
PACKET_PROFILING_LOGGER_END(p, logger->logger_id);
AppLayerParserSetTxLogged(p->proto, alproto, alstate, tx,
logger->id);
+ loggers_that_logged++;
}
next:
@@ -242,12 +251,27 @@
BUG_ON(logger != NULL && store == NULL);
}
- if (!logger_not_logged) {
- SCLogDebug("updating log tx_id %"PRIu64, tx_id);
- AppLayerParserSetTransactionLogId(f->alparser);
+ /* If all loggers logged set a flag and update the last tx_id
+ * that was logged.
+ *
+ * If not all loggers were logged we flag that there was a gap
+ * so any subsequent transactions in this loop don't increase
+ * the maximum ID that was logged. */
+ if (!gap && loggers_that_logged == number_of_loggers) {
+ logged = 1;
+ max_id = tx_id;
+ } else {
+ gap = 1;
}
}
+ /* Update the the last ID that has been logged with all
+ * transactions before it. */
+ if (logged) {
+ SCLogDebug("updating log tx_id %"PRIu64, max_id);
+ AppLayerParserSetTransactionLogId(f->alparser, max_id + 1);
+ }
+
end:
return TM_ECODE_OK;
}
diff -Nru suricata-3.2/src/queue.h suricata-3.2.1/src/queue.h
--- suricata-3.2/src/queue.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/queue.h 2017-02-15 08:54:12.000000000 +0100
@@ -82,12 +82,18 @@
* For details on the use of these macros, see the queue(3) manual page.
*/
-#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
+#if defined(__clang_analyzer__) || defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
#define _Q_INVALIDATE(a) ((a) = ((void *)-1))
#else
#define _Q_INVALIDATE(a)
#endif
+#if defined(__clang_analyzer__)
+#define _Q_ASSERT(a) assert((a))
+#else
+#define _Q_ASSERT(a)
+#endif
+
/*
* Singly-linked List definitions.
*/
@@ -377,9 +383,12 @@
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ _Q_ASSERT((elm)); \
+ _Q_ASSERT((head)); \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
+ _Q_ASSERT(*(head)->tqh_last); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
@@ -407,6 +416,7 @@
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+ _Q_ASSERT((head)->tqh_first != (elm)); \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
diff -Nru suricata-3.2/src/runmodes.c suricata-3.2.1/src/runmodes.c
--- suricata-3.2/src/runmodes.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/runmodes.c 2017-02-15 08:54:12.000000000 +0100
@@ -50,6 +50,8 @@
#include "source-pfring.h"
#include "tmqh-flow.h"
+#include "flow-manager.h"
+#include "counters.h"
#ifdef __SC_CUDA_SUPPORT__
#include "util-cuda-buffer.h"
@@ -392,7 +394,12 @@
/* Check if the alloted queues have at least 1 reader and writer */
TmValidateQueueState();
- return;
+ if (runmode != RUNMODE_UNIX_SOCKET) {
+ /* spawn management threads */
+ FlowManagerThreadSpawn();
+ FlowRecyclerThreadSpawn();
+ StatsSpawnThreads();
+ }
}
/**
diff -Nru suricata-3.2/src/runmode-unittests.c suricata-3.2.1/src/runmode-unittests.c
--- suricata-3.2/src/runmode-unittests.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/runmode-unittests.c 2017-02-15 08:54:12.000000000 +0100
@@ -128,77 +128,9 @@
void RegisterAllModules();
void TmqhSetup (void);
-/**
- * Run or list unittests
- *
- * \param list_unittests If set to 1, list unittests. Run them if set to 0.
- * \param regex_arg A regular expression to select unittests to run
- *
- * This function is terminal and will call exit after being called.
- */
-
-void RunUnittests(int list_unittests, char *regex_arg)
-{
#ifdef UNITTESTS
- /* Initializations for global vars, queues, etc (memsets, mutex init..) */
- GlobalInits();
- TimeInit();
- SupportFastPatternForSigMatchTypes();
-#ifdef HAVE_LUAJIT
- if (LuajitSetupStatesPool() != 0) {
- exit(EXIT_FAILURE);
- }
-#endif
-
- default_packet_size = DEFAULT_PACKET_SIZE;
-#ifdef __SC_CUDA_SUPPORT__
- /* Init the CUDA environment */
- SCCudaInitCudaEnvironment();
- CudaBufferInit();
-#endif
- /* load the pattern matchers */
- MpmTableSetup();
-#ifdef __SC_CUDA_SUPPORT__
- MpmCudaEnvironmentSetup();
-#endif
- SpmTableSetup();
-
- AppLayerSetup();
-
- /* hardcoded initialization code */
- SigTableSetup(); /* load the rule keywords */
- TmqhSetup();
-
- StorageInit();
- CIDRInit();
- SigParsePrepare();
-
-#ifdef DBG_MEM_ALLOC
- SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem);
-#endif
- SCReputationInitCtx();
- SCProtoNameInit();
-
- TagInitCtx();
- SCReferenceConfInit();
- SCClassConfInit();
-
- UtInitialize();
-
- RegisterAllModules();
-
- HostBitInitCtx();
-
- StorageFinalize();
- /* test and initialize the unittesting subsystem */
- if(regex_arg == NULL){
- regex_arg = ".*";
- UtRunSelftest(regex_arg); /* inits and cleans up again */
- }
-
- AppLayerHtpEnableRequestBodyCallback();
- AppLayerHtpNeedFileInspection();
-
+static void RegisterUnittests(void)
+{
UTHRegisterTests();
StreamTcpRegisterTests();
SigRegisterTests();
@@ -290,6 +222,75 @@
AppLayerUnittestsRegister();
MimeDecRegisterTests();
StreamingBufferRegisterTests();
+}
+#endif
+
+/**
+ * Run or list unittests
+ *
+ * \param list_unittests If set to 1, list unittests. Run them if set to 0.
+ * \param regex_arg A regular expression to select unittests to run
+ *
+ * This function is terminal and will call exit after being called.
+ */
+
+void RunUnittests(int list_unittests, char *regex_arg)
+{
+#ifdef UNITTESTS
+ /* Initializations for global vars, queues, etc (memsets, mutex init..) */
+ GlobalsInitPreConfig();
+
+#ifdef HAVE_LUAJIT
+ if (LuajitSetupStatesPool() != 0) {
+ exit(EXIT_FAILURE);
+ }
+#endif
+
+ default_packet_size = DEFAULT_PACKET_SIZE;
+ /* load the pattern matchers */
+ MpmTableSetup();
+#ifdef __SC_CUDA_SUPPORT__
+ MpmCudaEnvironmentSetup();
+#endif
+ SpmTableSetup();
+
+ AppLayerSetup();
+
+ /* hardcoded initialization code */
+ SigTableSetup(); /* load the rule keywords */
+ TmqhSetup();
+
+ StorageInit();
+ CIDRInit();
+ SigParsePrepare();
+
+#ifdef DBG_MEM_ALLOC
+ SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem);
+#endif
+ SCReputationInitCtx();
+ SCProtoNameInit();
+
+ TagInitCtx();
+ SCReferenceConfInit();
+ SCClassConfInit();
+
+ UtInitialize();
+
+ RegisterAllModules();
+
+ HostBitInitCtx();
+
+ StorageFinalize();
+ /* test and initialize the unittesting subsystem */
+ if(regex_arg == NULL){
+ regex_arg = ".*";
+ UtRunSelftest(regex_arg); /* inits and cleans up again */
+ }
+
+ AppLayerHtpEnableRequestBodyCallback();
+ AppLayerHtpNeedFileInspection();
+
+ RegisterUnittests();
if (list_unittests) {
UtListTests(regex_arg);
diff -Nru suricata-3.2/src/runmode-unix-socket.c suricata-3.2.1/src/runmode-unix-socket.c
--- suricata-3.2/src/runmode-unix-socket.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/runmode-unix-socket.c 2017-02-15 08:54:12.000000000 +0100
@@ -299,102 +299,57 @@
}
this->currentfile = NULL;
- /* needed by FlowForceReassembly */
- PacketPoolInit();
-
- /* handle graceful shutdown of the flow engine, it's helper
- * threads and the packet threads */
- FlowDisableFlowManagerThread();
- TmThreadDisableReceiveThreads();
- FlowForceReassembly();
- TmThreadDisablePacketThreads();
- FlowDisableFlowRecyclerThread();
-
- /* kill the stats threads */
- TmThreadKillThreadsFamily(TVT_MGMT);
- TmThreadClearThreadsFamily(TVT_MGMT);
-
- /* kill packet threads -- already in 'disabled' state */
- TmThreadKillThreadsFamily(TVT_PPT);
- TmThreadClearThreadsFamily(TVT_PPT);
-
- PacketPoolDestroy();
+ PostRunDeinit(RUNMODE_PCAP_FILE, NULL /* no ts */);
+ }
+ if (TAILQ_EMPTY(&this->files)) {
+ // nothing to do
+ return TM_ECODE_OK;
+ }
- /* mgt and ppt threads killed, we can run non thread-safe
- * shutdown functions */
- StatsReleaseResources();
- RunModeShutDown();
- FlowShutdown();
- IPPairShutdown();
- HostCleanup();
- StreamTcpFreeConfig(STREAM_VERBOSE);
- DefragDestroy();
- TmqResetQueues();
-#ifdef PROFILING
- if (profiling_rules_enabled)
- SCProfilingDump();
- SCProfilingDestroy();
-#endif
+ PcapFiles *cfile = TAILQ_FIRST(&this->files);
+ TAILQ_REMOVE(&this->files, cfile, next);
+ SCLogInfo("Starting run for '%s'", cfile->filename);
+ unix_manager_file_task_running = 1;
+ this->running = 1;
+ if (ConfSet("pcap-file.file", cfile->filename) != 1) {
+ SCLogError(SC_ERR_INVALID_ARGUMENTS,
+ "Can not set working file to '%s'", cfile->filename);
+ PcapFilesFree(cfile);
+ return TM_ECODE_FAILED;
}
- if (!TAILQ_EMPTY(&this->files)) {
- PcapFiles *cfile = TAILQ_FIRST(&this->files);
- TAILQ_REMOVE(&this->files, cfile, next);
- SCLogInfo("Starting run for '%s'", cfile->filename);
- unix_manager_file_task_running = 1;
- this->running = 1;
- if (ConfSet("pcap-file.file", cfile->filename) != 1) {
+ if (cfile->output_dir) {
+ if (ConfSet("default-log-dir", cfile->output_dir) != 1) {
SCLogError(SC_ERR_INVALID_ARGUMENTS,
- "Can not set working file to '%s'", cfile->filename);
+ "Can not set output dir to '%s'", cfile->output_dir);
PcapFilesFree(cfile);
return TM_ECODE_FAILED;
}
- if (cfile->output_dir) {
- if (ConfSet("default-log-dir", cfile->output_dir) != 1) {
- SCLogError(SC_ERR_INVALID_ARGUMENTS,
- "Can not set output dir to '%s'", cfile->output_dir);
- PcapFilesFree(cfile);
- return TM_ECODE_FAILED;
- }
- }
- if (cfile->tenant_id > 0) {
- char tstr[16];
- snprintf(tstr, sizeof(tstr), "%d", cfile->tenant_id);
- if (ConfSet("pcap-file.tenant-id", tstr) != 1) {
- SCLogError(SC_ERR_INVALID_ARGUMENTS,
- "Can not set working tenant-id to '%s'", tstr);
- PcapFilesFree(cfile);
- return TM_ECODE_FAILED;
- }
- } else {
- SCLogInfo("pcap-file.tenant-id not set");
- }
- this->currentfile = SCStrdup(cfile->filename);
- if (unlikely(this->currentfile == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "Failed file name allocation");
+ }
+ if (cfile->tenant_id > 0) {
+ char tstr[16];
+ snprintf(tstr, sizeof(tstr), "%d", cfile->tenant_id);
+ if (ConfSet("pcap-file.tenant-id", tstr) != 1) {
+ SCLogError(SC_ERR_INVALID_ARGUMENTS,
+ "Can not set working tenant-id to '%s'", tstr);
+ PcapFilesFree(cfile);
return TM_ECODE_FAILED;
}
- PcapFilesFree(cfile);
- StatsInit();
-#ifdef PROFILING
- SCProfilingRulesGlobalInit();
- SCProfilingKeywordsGlobalInit();
- SCProfilingSghsGlobalInit();
- SCProfilingInit();
-#endif /* PROFILING */
- DefragInit();
- FlowInitConfig(FLOW_QUIET);
- IPPairInitConfig(FLOW_QUIET);
- StreamTcpInitConfig(STREAM_VERBOSE);
- AppLayerRegisterGlobalCounters();
- RunModeInitializeOutputs();
- StatsSetupPostConfig();
- RunModeDispatch(RUNMODE_PCAP_FILE, NULL);
- FlowManagerThreadSpawn();
- FlowRecyclerThreadSpawn();
- StatsSpawnThreads();
- /* Un-pause all the paused threads */
- TmThreadContinueThreads();
+ } else {
+ SCLogInfo("pcap-file.tenant-id not set");
+ }
+ this->currentfile = SCStrdup(cfile->filename);
+ if (unlikely(this->currentfile == NULL)) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Failed file name allocation");
+ return TM_ECODE_FAILED;
}
+ PcapFilesFree(cfile);
+
+ PreRunInit(RUNMODE_PCAP_FILE);
+ PreRunPostPrivsDropInit(RUNMODE_PCAP_FILE);
+ RunModeDispatch(RUNMODE_PCAP_FILE, NULL);
+
+ /* Un-pause all the paused threads */
+ TmThreadContinueThreads();
return TM_ECODE_OK;
}
#endif
diff -Nru suricata-3.2/src/source-af-packet.c suricata-3.2.1/src/source-af-packet.c
--- suricata-3.2/src/source-af-packet.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/source-af-packet.c 2017-02-15 08:54:12.000000000 +0100
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011-2016 Open Information Security Foundation
+/* Copyright (C) 2011-2017 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
@@ -662,10 +662,23 @@
SCReturnInt(AFP_READ_OK);
}
-TmEcode AFPWritePacket(Packet *p)
+/**
+ * \brief AF packet write function.
+ *
+ * This function has to be called before the memory
+ * related to Packet in ring buffer is released.
+ *
+ * \param pointer to Packet
+ * \param version of capture: TPACKET_V2 or TPACKET_V3
+ * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
+ *
+ */
+static TmEcode AFPWritePacket(Packet *p, int version)
{
struct sockaddr_ll socket_address;
int socket;
+ uint8_t *pstart;
+ size_t plen;
if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) {
if (PACKET_TEST_ACTION(p, ACTION_DROP)) {
@@ -691,7 +704,31 @@
if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
SCMutexLock(&p->afp_v.peer->sock_protect);
socket = SC_ATOMIC_GET(p->afp_v.peer->socket);
- if (sendto(socket, GET_PKT_DATA(p), GET_PKT_LEN(p), 0,
+
+ if (version == TPACKET_V2) {
+ union thdr h;
+ h.raw = p->afp_v.relptr;
+ /* Copy VLAN header from ring memory. For post june 2011 kernel we test
+ * the flag. It is not defined for older kernel so we go best effort
+ * and test for non zero value of the TCI header. */
+ if (h.h2->tp_status & TP_STATUS_VLAN_VALID || h.h2->tp_vlan_tci) {
+ pstart = GET_PKT_DATA(p) - VLAN_HEADER_LEN;
+ plen = GET_PKT_LEN(p) + VLAN_HEADER_LEN;
+ /* move ethernet addresses */
+ memmove(pstart, GET_PKT_DATA(p), 2 * ETH_ALEN);
+ /* write vlan info */
+ *(uint16_t *)(pstart + 2 * ETH_ALEN) = htons(0x8100);
+ *(uint16_t *)(pstart + 2 * ETH_ALEN + 2) = htons(h.h2->tp_vlan_tci);
+ } else {
+ pstart = GET_PKT_DATA(p);
+ plen = GET_PKT_LEN(p);
+ }
+ } else {
+ pstart = GET_PKT_DATA(p);
+ plen = GET_PKT_LEN(p);
+ }
+
+ if (sendto(socket, pstart, plen, 0,
(struct sockaddr*) &socket_address,
sizeof(struct sockaddr_ll)) < 0) {
SCLogWarning(SC_ERR_SOCKET, "Sending packet failed on socket %d: %s",
@@ -712,7 +749,7 @@
/* Need to be in copy mode and need to detect early release
where Ethernet header could not be set (and pseudo packet) */
if ((p->afp_v.copy_mode != AFP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) {
- AFPWritePacket(p);
+ AFPWritePacket(p, TPACKET_V2);
}
if (AFPDerefSocket(p->afp_v.mpeer) == 0)
@@ -728,15 +765,17 @@
AFPV_CLEANUP(&p->afp_v);
}
+#ifdef HAVE_TPACKET_V3
void AFPReleasePacketV3(Packet *p)
{
/* Need to be in copy mode and need to detect early release
where Ethernet header could not be set (and pseudo packet) */
if ((p->afp_v.copy_mode != AFP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) {
- AFPWritePacket(p);
+ AFPWritePacket(p, TPACKET_V3);
}
PacketFreeOrRelease(p);
}
+#endif
void AFPReleasePacket(Packet *p)
{
@@ -1686,6 +1725,21 @@
}
#endif
+ /* Let's reserve head room so we can add the VLAN header in IPS
+ * or TAP mode before write the packet */
+ if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
+ /* Only one vlan is extracted from AFP header so
+ * one VLAN header length is enough. */
+ int reserve = VLAN_HEADER_LEN;
+ if (setsockopt(ptv->socket, SOL_PACKET, PACKET_RESERVE, (void *) &reserve,
+ sizeof(reserve)) < 0) {
+ SCLogError(SC_ERR_AFP_CREATE,
+ "Can't activate reserve on packet socket: %s",
+ strerror(errno));
+ return AFP_FATAL_ERROR;
+ }
+ }
+
/* Allocate RX ring */
#ifdef HAVE_TPACKET_V3
if (ptv->flags & AFP_TPACKET_V3) {
diff -Nru suricata-3.2/src/stream-tcp-reassemble.c suricata-3.2.1/src/stream-tcp-reassemble.c
--- suricata-3.2/src/stream-tcp-reassemble.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/stream-tcp-reassemble.c 2017-02-15 08:54:12.000000000 +0100
@@ -344,12 +344,21 @@
SCLogDebug("segpre->val %s", segpre->val);
uint16_t pktsize = 0;
- if (ByteExtractStringUint16(&pktsize, 10, strlen(segsize->val),
- segsize->val) == -1)
- {
- SCLogError(SC_ERR_INVALID_ARGUMENT, "segment packet size "
- "of %s is invalid", segsize->val);
- return -1;
+ if (strcmp("from_mtu", segsize->val) == 0) {
+ int mtu = g_default_mtu ? g_default_mtu : DEFAULT_MTU;
+ if (mtu < MINIMUM_MTU) {
+ FatalErrorOnInit(SC_ERR_INVALID_ARGUMENT, "invalid mtu %d", mtu);
+ continue;
+ }
+ pktsize = mtu - 40;
+ } else {
+ if (ByteExtractStringUint16(&pktsize, 10, strlen(segsize->val),
+ segsize->val) == -1)
+ {
+ SCLogError(SC_ERR_INVALID_ARGUMENT, "segment packet size "
+ "of %s is invalid", segsize->val);
+ return -1;
+ }
}
uint32_t prealloc = 0;
if (ByteExtractStringUint32(&prealloc, 10, strlen(segpre->val),
@@ -379,6 +388,10 @@
SCLogConfig("appended a segment pool for pktsize 65536");
}
} else if (npools == 0) {
+ int mtu = g_default_mtu;
+ if (mtu < MINIMUM_MTU)
+ mtu = DEFAULT_MTU;
+
/* defaults */
sizes[0].pktsize = 4;
sizes[0].prealloc = 256;
@@ -392,7 +405,7 @@
sizes[4].prealloc = 512;
sizes[5].pktsize = 768;
sizes[5].prealloc = 1024;
- sizes[6].pktsize = 1448;
+ sizes[6].pktsize = mtu - 40; // min size of ipv4+tcp hdrs
sizes[6].prealloc = 1024;
sizes[7].pktsize = 0xffff;
sizes[7].prealloc = 128;
diff -Nru suricata-3.2/src/suricata.c suricata-3.2.1/src/suricata.c
--- suricata-3.2/src/suricata.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/suricata.c 2017-02-15 08:54:12.000000000 +0100
@@ -116,6 +116,7 @@
#include "app-layer-htp.h"
#include "app-layer-ssl.h"
#include "app-layer-dns-tcp.h"
+#include "app-layer-dns-udp.h"
#include "app-layer-ssh.h"
#include "app-layer-ftp.h"
#include "app-layer-smtp.h"
@@ -211,7 +212,10 @@
int g_detect_disabled = 0;
/** set caps or not */
-int sc_set_caps;
+int sc_set_caps = FALSE;
+
+/** highest mtu of the interfaces we monitor */
+int g_default_mtu = 0;
int EngineModeIsIPS(void)
{
@@ -312,8 +316,14 @@
}
}
-void GlobalInits()
+void GlobalsInitPreConfig()
{
+#ifdef __SC_CUDA_SUPPORT__
+ /* Init the CUDA environment */
+ SCCudaInitCudaEnvironment();
+ CudaBufferInit();
+#endif
+
memset(trans_q, 0, sizeof(trans_q));
memset(data_queues, 0, sizeof(data_queues));
@@ -334,6 +344,80 @@
}
CreateLowercaseTable();
+
+ TimeInit();
+ SupportFastPatternForSigMatchTypes();
+}
+
+void GlobalsDestroy(SCInstance *suri)
+{
+ HostShutdown();
+ HTPFreeConfig();
+ HTPAtExitPrintStats();
+
+#ifdef DBG_MEM_ALLOC
+ SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem);
+#ifdef DBG_MEM_ALLOC_SKIP_STARTUP
+ print_mem_flag = 0;
+#endif
+#endif
+
+ AppLayerHtpPrintStats();
+
+ /* TODO this can do into it's own func */
+ DetectEngineCtx *de_ctx = DetectEngineGetCurrent();
+ if (de_ctx) {
+ DetectEngineMoveToFreeList(de_ctx);
+ DetectEngineDeReference(&de_ctx);
+ }
+ DetectEnginePruneFreeList();
+
+ AppLayerDeSetup();
+
+ TagDestroyCtx();
+
+ LiveDeviceListClean();
+ OutputDeregisterAll();
+ TimeDeinit();
+ SCProtoNameDeInit();
+ if (!suri->disabled_detect) {
+ SCReferenceConfDeinit();
+ SCClassConfDeinit();
+ }
+#ifdef HAVE_MAGIC
+ MagicDeinit();
+#endif
+ TmqhCleanup();
+ TmModuleRunDeInit();
+ ParseSizeDeinit();
+#ifdef HAVE_NSS
+ NSS_Shutdown();
+ PR_Cleanup();
+#endif
+
+#ifdef HAVE_AF_PACKET
+ AFPPeersListClean();
+#endif
+
+ SC_ATOMIC_DESTROY(engine_stage);
+
+#ifdef BUILD_HYPERSCAN
+ MpmHSGlobalCleanup();
+#endif
+
+#ifdef __SC_CUDA_SUPPORT__
+ if (PatternMatchDefaultMatcher() == MPM_AC_CUDA)
+ MpmCudaBufferDeSetup();
+ CudaHandlerFreeProfiles();
+#endif
+ ConfDeInit();
+#ifdef HAVE_LUAJIT
+ LuajitFreeStatesPool();
+#endif
+ SCLogDeInitLogModule();
+ DetectParseFreeRegexes();
+
+ SCPidfileRemove(suri->pid_filename);
}
/** \brief make sure threads can stop the engine by calling this
@@ -680,6 +764,9 @@
#ifdef TLS
strlcat(features, "TLS ", sizeof(features));
#endif
+#ifdef HAVE_MAGIC
+ strlcat(features, "MAGIC ", sizeof(features));
+#endif
if (strlen(features) == 0) {
strlcat(features, "none", sizeof(features));
}
@@ -954,10 +1041,11 @@
SCReturnInt(TM_ECODE_OK);
}
-static void SCInstanceInit(SCInstance *suri)
+static void SCInstanceInit(SCInstance *suri, const char *progname)
{
memset(suri, 0x00, sizeof(*suri));
+ suri->progname = progname;
suri->run_mode = RUNMODE_UNKNOWN;
memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev));
@@ -1019,13 +1107,15 @@
gettimeofday(&suri->start_time, NULL);
}
-static void SCPrintElapsedTime(SCInstance *suri)
+static void SCPrintElapsedTime(struct timeval *start_time)
{
+ if (start_time == NULL)
+ return;
struct timeval end_time;
memset(&end_time, 0, sizeof(end_time));
gettimeofday(&end_time, NULL);
- uint64_t milliseconds = ((end_time.tv_sec - suri->start_time.tv_sec) * 1000) +
- (((1000000 + end_time.tv_usec - suri->start_time.tv_usec) / 1000) - 1000);
+ uint64_t milliseconds = ((end_time.tv_sec - start_time->tv_sec) * 1000) +
+ (((1000000 + end_time.tv_usec - start_time->tv_usec) / 1000) - 1000);
SCLogInfo("time elapsed %.3fs", (float)milliseconds/(float)1000);
}
@@ -1108,6 +1198,231 @@
return TM_ECODE_OK;
}
+static void ParseCommandLineAFL(const char *opt_name, char *opt_arg)
+{
+#ifdef AFLFUZZ_RULES
+ if(strcmp(opt_name, "afl-rules") == 0) {
+ MpmTableSetup();
+ SpmTableSetup();
+ exit(RuleParseDataFromFile(opt_arg));
+ } else
+#endif
+#ifdef AFLFUZZ_APPLAYER
+ if(strcmp(opt_name, "afl-http-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterHTPParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_HTTP, opt_arg));
+ } else if(strcmp(opt_name, "afl-http") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterHTPParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_HTTP, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-tls-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterSSLParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_TLS, opt_arg));
+ } else if(strcmp(opt_name, "afl-tls") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterSSLParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_TLS, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-dns-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ RegisterDNSUDPParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_UDP, ALPROTO_DNS, opt_arg));
+ } else if(strcmp(opt_name, "afl-dns") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ AppLayerParserSetup();
+ RegisterDNSUDPParsers();
+ exit(AppLayerParserFromFile(IPPROTO_UDP, ALPROTO_DNS, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-dnstcp-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ RegisterDNSTCPParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_DNS, opt_arg));
+ } else if(strcmp(opt_name, "afl-dnstcp") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ AppLayerParserSetup();
+ RegisterDNSTCPParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_DNS, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-ssh-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ RegisterSSHParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_SSH, opt_arg));
+ } else if(strcmp(opt_name, "afl-ssh") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterSSHParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_SSH, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-ftp-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterFTPParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_FTP, opt_arg));
+ } else if(strcmp(opt_name, "afl-ftp") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterFTPParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_FTP, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-smtp-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterSMTPParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_SMTP, opt_arg));
+ } else if(strcmp(opt_name, "afl-smtp") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterSMTPParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_SMTP, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-smb-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ RegisterSMBParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_SMB, opt_arg));
+ } else if(strcmp(opt_name, "afl-smb") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ AppLayerParserSetup();
+ RegisterSMBParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_SMB, opt_arg));
+
+ } else if(strcmp(opt_name, "afl-modbus-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ AppLayerParserSetup();
+ RegisterModbusParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_MODBUS, opt_arg));
+ } else if(strcmp(opt_name, "afl-modbus") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ AppLayerParserSetup();
+ RegisterModbusParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_MODBUS, opt_arg));
+ } else if(strcmp(opt_name, "afl-enip-request") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ AppLayerParserSetup();
+ RegisterENIPTCPParsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_ENIP, opt_arg));
+ } else if(strcmp(opt_name, "afl-enip") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ AppLayerParserSetup();
+ RegisterENIPTCPParsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_ENIP, opt_arg));
+ } else if(strcmp(opt_name, "afl-dnp3-request") == 0) {
+ AppLayerParserSetup();
+ RegisterDNP3Parsers();
+ exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_DNP3, opt_arg));
+ } else if(strcmp(opt_name, "afl-dnp3") == 0) {
+ AppLayerParserSetup();
+ RegisterDNP3Parsers();
+ exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_DNP3, opt_arg));
+ } else
+#endif
+#ifdef AFLFUZZ_MIME
+ if(strcmp(opt_name, "afl-mime") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ exit(MimeParserDataFromFile(opt_arg));
+ } else
+#endif
+#ifdef AFLFUZZ_DECODER
+ if(strstr(opt_name, "afl-decoder-ppp") != NULL) {
+ StatsInit();
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ if (strcmp(opt_name, "afl-decoder-ppp") == 0)
+ exit(DecoderParseDataFromFile(opt_arg, DecodePPP));
+ else
+ exit(DecoderParseDataFromFileSerie(opt_arg, DecodePPP));
+ } else if(strstr(opt_name, "afl-decoder-ipv4") != NULL) {
+ StatsInit();
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ if (strcmp(opt_name, "afl-decoder-ipv4") == 0)
+ exit(DecoderParseDataFromFile(opt_arg, DecodeIPV4));
+ else
+ exit(DecoderParseDataFromFileSerie(opt_arg, DecodeIPV4));
+ } else if(strstr(opt_name, "afl-decoder-ipv6") != NULL) {
+ StatsInit();
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ if (strcmp(opt_name, "afl-decoder-ipv6") == 0)
+ exit(DecoderParseDataFromFile(opt_arg, DecodeIPV6));
+ else
+ exit(DecoderParseDataFromFileSerie(opt_arg, DecodeIPV6));
+ } else if(strstr(opt_name, "afl-decoder-ethernet") != NULL) {
+ StatsInit();
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ if (strcmp(opt_name, "afl-decoder-ethernet") == 0)
+ exit(DecoderParseDataFromFile(opt_arg, DecodeEthernet));
+ else
+ exit(DecoderParseDataFromFileSerie(opt_arg, DecodeEthernet));
+ } else if(strstr(opt_name, "afl-decoder-erspan") != NULL) {
+ StatsInit();
+ MpmTableSetup();
+ SpmTableSetup();
+ AppLayerProtoDetectSetup();
+ if (strcmp(opt_name, "afl-decoder-erspan") == 0)
+ exit(DecoderParseDataFromFile(opt_arg, DecodeERSPAN));
+ else
+ exit(DecoderParseDataFromFileSerie(opt_arg, DecodeERSPAN));
+ } else
+#endif
+#ifdef AFLFUZZ_DER
+ if(strcmp(opt_name, "afl-der") == 0) {
+ //printf("arg: //%s\n", opt_arg);
+ exit(DerParseDataFromFile(opt_arg));
+ } else
+#endif
+ {
+ abort();
+ }
+}
+
static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
{
int opt;
@@ -1171,6 +1486,15 @@
{"afl-rules", required_argument, 0 , 0},
{"afl-mime", required_argument, 0 , 0},
{"afl-decoder-ppp", required_argument, 0 , 0},
+ {"afl-decoder-ppp-serie", required_argument, 0 , 0},
+ {"afl-decoder-ethernet", required_argument, 0 , 0},
+ {"afl-decoder-ethernet-serie", required_argument, 0 , 0},
+ {"afl-decoder-erspan", required_argument, 0 , 0},
+ {"afl-decoder-erspan-serie", required_argument, 0 , 0},
+ {"afl-decoder-ipv4", required_argument, 0 , 0},
+ {"afl-decoder-ipv4-serie", required_argument, 0 , 0},
+ {"afl-decoder-ipv6", required_argument, 0 , 0},
+ {"afl-decoder-ipv6-serie", required_argument, 0 , 0},
{"afl-der", required_argument, 0, 0},
#ifdef BUILD_UNIX_SOCKET
@@ -1312,173 +1636,8 @@
if (ParseCommandLinePcapLive(suri, optarg) != TM_ECODE_OK) {
return TM_ECODE_FAILED;
}
-#ifdef AFLFUZZ_RULES
- } else if(strcmp((long_opts[option_index]).name, "afl-rules") == 0) {
- MpmTableSetup();
- SpmTableSetup();
- exit(RuleParseDataFromFile(optarg));
-#endif
-#ifdef AFLFUZZ_APPLAYER
- } else if(strcmp((long_opts[option_index]).name, "afl-http-request") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterHTPParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_HTTP, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-http") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterHTPParsers();
- exit(AppLayerParserFromFile(ALPROTO_HTTP, optarg));
-
- } else if(strcmp((long_opts[option_index]).name, "afl-tls-request") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterSSLParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_TLS, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-tls") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterSSLParsers();
- exit(AppLayerParserFromFile(ALPROTO_TLS, optarg));
-
- } else if(strcmp((long_opts[option_index]).name, "afl-dns-request") == 0) {
- //printf("arg: //%s\n", optarg);
- RegisterDNSTCPParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_DNS, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-dns") == 0) {
- //printf("arg: //%s\n", optarg);
- AppLayerParserSetup();
- RegisterDNSTCPParsers();
- exit(AppLayerParserFromFile(ALPROTO_DNS, optarg));
-
- } else if(strcmp((long_opts[option_index]).name, "afl-ssh-request") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- RegisterSSHParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_SSH, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-ssh") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterSSHParsers();
- exit(AppLayerParserFromFile(ALPROTO_SSH, optarg));
-
- } else if(strcmp((long_opts[option_index]).name, "afl-ftp-request") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterFTPParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_FTP, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-ftp") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterFTPParsers();
- exit(AppLayerParserFromFile(ALPROTO_FTP, optarg));
-
- } else if(strcmp((long_opts[option_index]).name, "afl-smtp-request") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterSMTPParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_SMTP, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-smtp") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterSMTPParsers();
- exit(AppLayerParserFromFile(ALPROTO_SMTP, optarg));
-
- } else if(strcmp((long_opts[option_index]).name, "afl-smb-request") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- RegisterSMBParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_SMB, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-smb") == 0) {
- //printf("arg: //%s\n", optarg);
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- AppLayerParserSetup();
- RegisterSMBParsers();
- exit(AppLayerParserFromFile(ALPROTO_SMB, optarg));
-
- } else if(strcmp((long_opts[option_index]).name, "afl-modbus-request") == 0) {
- //printf("arg: //%s\n", optarg);
- AppLayerParserSetup();
- RegisterModbusParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_MODBUS, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-modbus") == 0) {
- //printf("arg: //%s\n", optarg);
- AppLayerParserSetup();
- RegisterModbusParsers();
- exit(AppLayerParserFromFile(ALPROTO_MODBUS, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-enip-request") == 0) {
- //printf("arg: //%s\n", optarg);
- AppLayerParserSetup();
- RegisterENIPTCPParsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_ENIP, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-enip") == 0) {
- //printf("arg: //%s\n", optarg);
- AppLayerParserSetup();
- RegisterENIPTCPParsers();
- exit(AppLayerParserFromFile(ALPROTO_ENIP, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-dnp3-request") == 0) {
- AppLayerParserSetup();
- RegisterDNP3Parsers();
- exit(AppLayerParserRequestFromFile(ALPROTO_DNP3, optarg));
- } else if(strcmp((long_opts[option_index]).name, "afl-dnp3") == 0) {
- AppLayerParserSetup();
- RegisterDNP3Parsers();
- exit(AppLayerParserFromFile(ALPROTO_DNP3, optarg));
-#endif
-#ifdef AFLFUZZ_MIME
- } else if(strcmp((long_opts[option_index]).name, "afl-mime") == 0) {
- //printf("arg: //%s\n", optarg);
- exit(MimeParserDataFromFile(optarg));
-#endif
-#ifdef AFLFUZZ_DECODER
- } else if(strcmp((long_opts[option_index]).name, "afl-decoder-ppp") == 0) {
- StatsInit();
- MpmTableSetup();
- SpmTableSetup();
- AppLayerProtoDetectSetup();
- DefragInit();
- FlowInitConfig(FLOW_QUIET);
- //printf("arg: //%s\n", optarg);
- exit(DecoderParseDataFromFile(optarg, DecodePPP));
-#endif
-#ifdef AFLFUZZ_DER
- } else if(strcmp((long_opts[option_index]).name, "afl-der") == 0) {
- //printf("arg: //%s\n", optarg);
- exit(DerParseDataFromFile(optarg));
-#endif
+ } else if(strncmp((long_opts[option_index]).name, "afl-", 4) == 0) {
+ ParseCommandLineAFL((long_opts[option_index]).name, optarg);
} else if(strcmp((long_opts[option_index]).name, "simulate-ips") == 0) {
SCLogInfo("Setting IPS mode");
EngineModeSetIPS();
@@ -2029,6 +2188,89 @@
return TM_ECODE_OK;
}
+/* initialization code for both the main modes and for
+ * unix socket mode.
+ *
+ * Will be run once per pcap in unix-socket mode */
+void PreRunInit(const int runmode)
+{
+ if (runmode == RUNMODE_UNIX_SOCKET)
+ return;
+
+ StatsInit();
+#ifdef PROFILING
+ SCProfilingRulesGlobalInit();
+ SCProfilingKeywordsGlobalInit();
+ SCProfilingSghsGlobalInit();
+ SCProfilingInit();
+#endif /* PROFILING */
+ DefragInit();
+ FlowInitConfig(FLOW_QUIET);
+ IPPairInitConfig(FLOW_QUIET);
+ StreamTcpInitConfig(STREAM_VERBOSE);
+ AppLayerRegisterGlobalCounters();
+}
+
+/* tasks we need to run before packets start flowing,
+ * but after we dropped privs */
+void PreRunPostPrivsDropInit(const int runmode)
+{
+ if (runmode == RUNMODE_UNIX_SOCKET)
+ return;
+
+ RunModeInitializeOutputs();
+ StatsSetupPostConfig();
+}
+
+/* clean up / shutdown code for both the main modes and for
+ * unix socket mode.
+ *
+ * Will be run once per pcap in unix-socket mode */
+void PostRunDeinit(const int runmode, struct timeval *start_time)
+{
+ if (runmode == RUNMODE_UNIX_SOCKET)
+ return;
+
+ /* needed by FlowForceReassembly */
+ PacketPoolInit();
+
+ /* handle graceful shutdown of the flow engine, it's helper
+ * threads and the packet threads */
+ FlowDisableFlowManagerThread();
+ TmThreadDisableReceiveThreads();
+ FlowForceReassembly();
+ TmThreadDisablePacketThreads();
+ SCPrintElapsedTime(start_time);
+ FlowDisableFlowRecyclerThread();
+
+ /* kill the stats threads */
+ TmThreadKillThreadsFamily(TVT_MGMT);
+ TmThreadClearThreadsFamily(TVT_MGMT);
+
+ /* kill packet threads -- already in 'disabled' state */
+ TmThreadKillThreadsFamily(TVT_PPT);
+ TmThreadClearThreadsFamily(TVT_PPT);
+
+ PacketPoolDestroy();
+
+ /* mgt and ppt threads killed, we can run non thread-safe
+ * shutdown functions */
+ StatsReleaseResources();
+ RunModeShutDown();
+ FlowShutdown();
+ IPPairShutdown();
+ HostCleanup();
+ StreamTcpFreeConfig(STREAM_VERBOSE);
+ DefragDestroy();
+ TmqResetQueues();
+#ifdef PROFILING
+ if (profiling_rules_enabled)
+ SCProfilingDump();
+ SCProfilingDestroy();
+#endif
+}
+
+
int StartInternalRunMode(SCInstance *suri, int argc, char **argv)
{
/* Treat internal running mode */
@@ -2191,6 +2433,8 @@
dev[len-1] = '\0';
}
}
+ int mtu = GetIfaceMTU(dev);
+ g_default_mtu = MAX(mtu, g_default_mtu);
unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(dev);
if (iface_max_packet_size > default_packet_size)
@@ -2200,6 +2444,7 @@
break;
/* fall through */
default:
+ g_default_mtu = DEFAULT_MTU;
default_packet_size = DEFAULT_PACKET_SIZE;
}
} else {
@@ -2215,6 +2460,72 @@
return TM_ECODE_OK;
}
+
+static void PostRunStartedDetectSetup(SCInstance *suri)
+{
+ /* registering signal handlers we use. We register usr2 here, so that one
+ * can't call it during the first sig load phase or while threads are still
+ * starting up. */
+ if (DetectEngineEnabled() && suri->sig_file == NULL &&
+ suri->delayed_detect == 0)
+ UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
+
+ if (suri->delayed_detect) {
+ /* force 'reload', this will load the rules and swap engines */
+ DetectEngineReload(suri);
+ SCLogNotice("Signature(s) loaded, Detect thread(s) activated.");
+ }
+}
+
+static void PostConfLoadedDetectSetup(SCInstance *suri)
+{
+ DetectEngineCtx *de_ctx = NULL;
+ if (!suri->disabled_detect) {
+ SCClassConfInit();
+ SCReferenceConfInit();
+ SetupDelayedDetect(suri);
+ int mt_enabled = 0;
+ (void)ConfGetBool("multi-detect.enabled", &mt_enabled);
+ int default_tenant = 0;
+ if (mt_enabled)
+ (void)ConfGetBool("multi-detect.default", &default_tenant);
+ if (DetectEngineMultiTenantSetup() == -1) {
+ SCLogError(SC_ERR_INITIALIZATION, "initializing multi-detect "
+ "detection engine contexts failed.");
+ exit(EXIT_FAILURE);
+ }
+ if ((suri->delayed_detect || (mt_enabled && !default_tenant)) &&
+ (suri->run_mode != RUNMODE_CONF_TEST)) {
+ de_ctx = DetectEngineCtxInitMinimal();
+ } else {
+ de_ctx = DetectEngineCtxInit();
+ }
+ if (de_ctx == NULL) {
+ SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine "
+ "context failed.");
+ exit(EXIT_FAILURE);
+ }
+
+#ifdef __SC_CUDA_SUPPORT__
+ if (PatternMatchDefaultMatcher() == MPM_AC_CUDA)
+ CudaVarsSetDeCtx(de_ctx);
+#endif /* __SC_CUDA_SUPPORT__ */
+
+ if (!de_ctx->minimal) {
+ if (LoadSignatures(de_ctx, suri) != TM_ECODE_OK)
+ exit(EXIT_FAILURE);
+ if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) {
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ DetectEngineAddToMaster(de_ctx);
+ } else {
+ /* tell the app layer to consider only the log id */
+ RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveLogOnly);
+ }
+}
+
/**
* This function is meant to contain code that needs
* to be run once the configuration has been loaded.
@@ -2316,9 +2627,6 @@
/* Load the Host-OS lookup. */
SCHInfoLoadFromConfig();
- if (suri->run_mode != RUNMODE_UNIX_SOCKET) {
- DefragInit();
- }
if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) {
SCLogInfo("== Carrying out Engine Analysis ==");
@@ -2338,14 +2646,6 @@
StorageInit();
CIDRInit();
SigParsePrepare();
-#ifdef PROFILING
- if (suri->run_mode != RUNMODE_UNIX_SOCKET) {
- SCProfilingRulesGlobalInit();
- SCProfilingKeywordsGlobalInit();
- SCProfilingSghsGlobalInit();
- SCProfilingInit();
- }
-#endif /* PROFILING */
SCReputationInitCtx();
SCProtoNameInit();
@@ -2397,43 +2697,82 @@
}
HostInitConfig(HOST_VERBOSE);
-
+#ifdef HAVE_MAGIC
if (MagicInit() != 0)
SCReturnInt(TM_ECODE_FAILED);
-
+#endif
SCAsn1LoadConfig();
CoredumpLoadConfig();
+ PreRunInit(suri->run_mode);
+
SCReturnInt(TM_ECODE_OK);
}
-int main(int argc, char **argv)
+static void SuricataMainLoop(SCInstance *suri)
{
- SCInstance suri;
+ while(1) {
+ if (sigterm_count || sigint_count) {
+ suricata_ctl_flags |= SURICATA_STOP;
+ }
+
+ if (suricata_ctl_flags & SURICATA_STOP) {
+ SCLogNotice("Signal Received. Stopping engine.");
+ break;
+ }
+
+ TmThreadCheckThreadState();
- SCInstanceInit(&suri);
- suri.progname = argv[0];
+ if (sighup_count > 0) {
+ OutputNotifyFileRotation();
+ sighup_count--;
+ }
- sc_set_caps = FALSE;
+ if (sigusr2_count > 0) {
+ if (suri->sig_file != NULL) {
+ SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload not "
+ "possible if -s or -S option used at runtime.");
+ sigusr2_count--;
+ } else {
+ if (!(DetectEngineReloadIsStart())) {
+ DetectEngineReloadStart();
+ DetectEngineReload(suri);
+ DetectEngineReloadSetDone();
+ sigusr2_count--;
+ }
+ }
+
+ } else if (DetectEngineReloadIsStart()) {
+ if (suri->sig_file != NULL) {
+ SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload not "
+ "possible if -s or -S option used at runtime.");
+ DetectEngineReloadSetDone();
+ } else {
+ DetectEngineReload(suri);
+ DetectEngineReloadSetDone();
+ }
+ }
+
+ usleep(10* 1000);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ SCInstance suri;
+ SCInstanceInit(&suri, argv[0]);
SC_ATOMIC_INIT(engine_stage);
/* initialize the logging subsys */
SCLogInitLogModule(NULL);
- if (SCSetThreadName("Suricata-Main") < 0) {
- SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name");
- }
+ (void)SCSetThreadName("Suricata-Main");
ParseSizeInit();
-
RunModeRegisterRunModes();
- /* By default use IDS mode, but if nfq or ipfw
- * are specified, IPS mode will overwrite this */
- EngineModeSetIDS();
-
#ifdef OS_WIN32
/* service initialization */
if (WindowsInit(argc, argv) != 0) {
@@ -2459,19 +2798,8 @@
exit(EXIT_FAILURE);
}
-#ifdef __SC_CUDA_SUPPORT__
- /* Init the CUDA environment */
- SCCudaInitCudaEnvironment();
- CudaBufferInit();
-#endif
-
/* Initializations for global vars, queues, etc (memsets, mutex init..) */
- GlobalInits();
- TimeInit();
- SupportFastPatternForSigMatchTypes();
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- StatsInit();
- }
+ GlobalsInitPreConfig();
/* Load yaml configuration file if provided. */
if (LoadYamlConfig(&suri) != TM_ECODE_OK) {
@@ -2488,7 +2816,6 @@
SCLogLoadConfig(suri.daemon, suri.verbose);
SCPrintVersion();
-
UtilCpuPrintSummary();
if (ParseInterfacesList(suri.run_mode, suri.pcap_dev) != TM_ECODE_OK) {
@@ -2498,93 +2825,23 @@
if (PostConfLoadedSetup(&suri) != TM_ECODE_OK) {
exit(EXIT_FAILURE);
}
-
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- FlowInitConfig(FLOW_VERBOSE);
- StreamTcpInitConfig(STREAM_VERBOSE);
- IPPairInitConfig(IPPAIR_VERBOSE);
- AppLayerRegisterGlobalCounters();
- }
-
- DetectEngineCtx *de_ctx = NULL;
- if (!suri.disabled_detect) {
- SCClassConfInit();
- SCReferenceConfInit();
- SetupDelayedDetect(&suri);
- int mt_enabled = 0;
- (void)ConfGetBool("multi-detect.enabled", &mt_enabled);
- int default_tenant = 0;
- if (mt_enabled)
- (void)ConfGetBool("multi-detect.default", &default_tenant);
- if (DetectEngineMultiTenantSetup() == -1) {
- SCLogError(SC_ERR_INITIALIZATION, "initializing multi-detect "
- "detection engine contexts failed.");
- exit(EXIT_FAILURE);
- }
- if ((suri.delayed_detect || (mt_enabled && !default_tenant)) &&
- (suri.run_mode != RUNMODE_CONF_TEST)) {
- de_ctx = DetectEngineCtxInitMinimal();
- } else {
- de_ctx = DetectEngineCtxInit();
- }
- if (de_ctx == NULL) {
- SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine "
- "context failed.");
- exit(EXIT_FAILURE);
- }
-
-#ifdef __SC_CUDA_SUPPORT__
- if (PatternMatchDefaultMatcher() == MPM_AC_CUDA)
- CudaVarsSetDeCtx(de_ctx);
-#endif /* __SC_CUDA_SUPPORT__ */
-
- if (!de_ctx->minimal) {
- if (LoadSignatures(de_ctx, &suri) != TM_ECODE_OK)
- exit(EXIT_FAILURE);
- if (suri.run_mode == RUNMODE_ENGINE_ANALYSIS) {
- exit(EXIT_SUCCESS);
- }
- }
-
- DetectEngineAddToMaster(de_ctx);
- } else {
- /* tell the app layer to consider only the log id */
- RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveLogOnly);
- }
-
- SCSetStartTime(&suri);
+ PostConfLoadedDetectSetup(&suri);
SCDropMainThreadCaps(suri.userid, suri.groupid);
-
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- RunModeInitializeOutputs();
- StatsSetupPostConfig();
- }
+ PreRunPostPrivsDropInit(suri.run_mode);
if (suri.run_mode == RUNMODE_CONF_TEST){
SCLogNotice("Configuration provided was successfully loaded. Exiting.");
+#ifdef HAVE_MAGIC
MagicDeinit();
+#endif
exit(EXIT_SUCCESS);
}
+ SCSetStartTime(&suri);
RunModeDispatch(suri.run_mode, suri.runmode_custom_mode);
-
- /* In Unix socket runmode, Flow manager is started on demand */
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- /* Spawn the unix socket manager thread */
- int unix_socket = ConfUnixSocketIsEnable();
- if (unix_socket == 1) {
- UnixManagerThreadSpawn(0);
-#ifdef BUILD_UNIX_SOCKET
- UnixManagerRegisterCommand("iface-stat", LiveDeviceIfaceStat, NULL,
- UNIX_CMD_TAKE_ARGS);
- UnixManagerRegisterCommand("iface-list", LiveDeviceIfaceList, NULL, 0);
-#endif
- }
- /* Spawn the flow manager thread */
- FlowManagerThreadSpawn();
- FlowRecyclerThreadSpawn();
- StatsSpawnThreads();
+ UnixManagerThreadSpawnNonRunmode();
}
/* Wait till all the threads have been initialized */
@@ -2599,19 +2856,8 @@
/* Un-pause all the paused threads */
TmThreadContinueThreads();
- /* registering singal handlers we use. We register usr2 here, so that one
- * can't call it during the first sig load phase or while threads are still
- * starting up. */
- if (DetectEngineEnabled() && suri.sig_file == NULL &&
- suri.delayed_detect == 0)
- UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
-
- if (suri.delayed_detect) {
- /* force 'reload', this will load the rules and swap engines */
- DetectEngineReload(&suri);
- SCLogNotice("Signature(s) loaded, Detect thread(s) activated.");
- }
+ PostRunStartedDetectSetup(&suri);
#ifdef DBG_MEM_ALLOC
SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem);
@@ -2620,181 +2866,17 @@
#endif
#endif
- int engine_retval = EXIT_SUCCESS;
- while(1) {
- if (sigterm_count || sigint_count) {
- suricata_ctl_flags |= SURICATA_STOP;
- }
-
- if (suricata_ctl_flags & SURICATA_STOP) {
- SCLogNotice("Signal Received. Stopping engine.");
- break;
- }
-
- TmThreadCheckThreadState();
-
- if (sighup_count > 0) {
- OutputNotifyFileRotation();
- sighup_count--;
- }
-
- if (sigusr2_count > 0) {
- if (suri.sig_file != NULL) {
- SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload not "
- "possible if -s or -S option used at runtime.");
- sigusr2_count--;
- } else {
- if (!(DetectEngineReloadIsStart())) {
- DetectEngineReloadStart();
- DetectEngineReload(&suri);
- DetectEngineReloadSetDone();
- sigusr2_count--;
- }
- }
-
- } else if (DetectEngineReloadIsStart()) {
- if (suri.sig_file != NULL) {
- SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload not "
- "possible if -s or -S option used at runtime.");
- DetectEngineReloadSetDone();
- } else {
- DetectEngineReload(&suri);
- DetectEngineReloadSetDone();
- }
- }
-
- usleep(10* 1000);
- }
+ SuricataMainLoop(&suri);
/* Update the engine stage/status flag */
(void) SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT);
UnixSocketKillSocketThread();
-
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- /* First we need to disable the flow manager thread */
- FlowDisableFlowManagerThread();
- }
-
-
- /* Disable packet acquisition first */
- TmThreadDisableReceiveThreads();
-
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- /* we need a packet pool for FlowForceReassembly */
- PacketPoolInit();
-
- FlowForceReassembly();
- /* kill receive threads when they have processed all
- * flow timeout packets */
- TmThreadDisablePacketThreads();
- }
-
- SCPrintElapsedTime(&suri);
-
- /* before TmThreadKillThreads, as otherwise that kills it
- * but more slowly */
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- FlowDisableFlowRecyclerThread();
- }
-
+ PostRunDeinit(suri.run_mode, &suri.start_time);
/* kill remaining threads */
TmThreadKillThreads();
+ GlobalsDestroy(&suri);
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- /* destroy the packet pool for flow reassembly after all
- * the other threads are gone. */
- PacketPoolDestroy();
-
- StatsReleaseResources();
- IPPairShutdown();
- FlowShutdown();
- StreamTcpFreeConfig(STREAM_VERBOSE);
- }
- HostShutdown();
-
- HTPFreeConfig();
- HTPAtExitPrintStats();
-
-#ifdef DBG_MEM_ALLOC
- SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem);
-#ifdef DBG_MEM_ALLOC_SKIP_STARTUP
- print_mem_flag = 0;
-#endif
-#endif
-
- SCPidfileRemove(suri.pid_filename);
-
- AppLayerHtpPrintStats();
-
- /** TODO this can do into it's own func */
- de_ctx = DetectEngineGetCurrent();
- if (de_ctx) {
- DetectEngineMoveToFreeList(de_ctx);
- DetectEngineDeReference(&de_ctx);
- }
- DetectEnginePruneFreeList();
-
- AppLayerDeSetup();
-
- TagDestroyCtx();
-
- LiveDeviceListClean();
- RunModeShutDown();
- OutputDeregisterAll();
- TimeDeinit();
- SCProtoNameDeInit();
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- DefragDestroy();
- }
- if (!suri.disabled_detect) {
- SCReferenceConfDeinit();
- SCClassConfDeinit();
- }
- MagicDeinit();
- TmqhCleanup();
- TmModuleRunDeInit();
- ParseSizeDeinit();
-#ifdef HAVE_NSS
- NSS_Shutdown();
- PR_Cleanup();
-#endif
-
-#ifdef HAVE_AF_PACKET
- AFPPeersListClean();
-#endif
-
-#ifdef PROFILING
- if (suri.run_mode != RUNMODE_UNIX_SOCKET) {
- if (profiling_rules_enabled)
- SCProfilingDump();
- SCProfilingDestroy();
- }
-#endif
-
-#ifdef OS_WIN32
- if (daemon) {
- return 0;
- }
-#endif /* OS_WIN32 */
-
- SC_ATOMIC_DESTROY(engine_stage);
-
-#ifdef BUILD_HYPERSCAN
- MpmHSGlobalCleanup();
-#endif
-
-#ifdef __SC_CUDA_SUPPORT__
- if (PatternMatchDefaultMatcher() == MPM_AC_CUDA)
- MpmCudaBufferDeSetup();
- CudaHandlerFreeProfiles();
-#endif
- ConfDeInit();
-#ifdef HAVE_LUAJIT
- LuajitFreeStatesPool();
-#endif
- SCLogDeInitLogModule();
- DetectParseFreeRegexes();
- exit(engine_retval);
+ exit(EXIT_SUCCESS);
}
diff -Nru suricata-3.2/src/suricata-common.h suricata-3.2.1/src/suricata-common.h
--- suricata-3.2/src/suricata-common.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/suricata-common.h 2017-02-15 08:54:12.000000000 +0100
@@ -225,15 +225,8 @@
#endif
#endif
-#if CPPCHECK==1
-#define BUG_ON(x) if (((x))) exit(1)
-#else
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#define BUG_ON(x) assert(!(x))
-#else
-#define BUG_ON(x)
-#endif
+#ifdef HAVE_MAGIC
+#include <magic.h>
#endif
/* we need this to stringify the defines which are supplied at compiletime see:
@@ -241,6 +234,23 @@
#define xstr(s) str(s)
#define str(s) #s
+#if CPPCHECK==1
+ #define BUG_ON(x) if (((x))) exit(1)
+#else
+ #if defined HAVE_ASSERT_H && !defined NDEBUG
+ #include <assert.h>
+ #define BUG_ON(x) assert(!(x))
+ #else
+ #define BUG_ON(x) do { \
+ if (((x))) { \
+ fprintf(stderr, "BUG at %s:%d(%s)\n", __FILE__, __LINE__, __func__); \
+ fprintf(stderr, "Code: '%s'\n", xstr((x))); \
+ exit(EXIT_FAILURE); \
+ } \
+ } while(0)
+ #endif
+#endif
+
/** type for the internal signature id. Since it's used in the matching engine
* extensively keeping this as small as possible reduces the overall memory
* footprint of the engine. Set to uint32_t if the engine needs to support
@@ -309,10 +319,13 @@
#define MAX(x, y) (((x)<(y))?(y):(x))
#endif
+#define BIT_U8(n) ((uint8_t)(1 << (n)))
#define BIT_U16(n) ((uint16_t)(1 << (n)))
#define BIT_U32(n) (1UL << (n))
#define BIT_U64(n) (1ULL << (n))
+#define WARN_UNUSED __attribute__((warn_unused_result))
+
typedef enum PacketProfileDetectId_ {
PROF_DETECT_IPONLY,
PROF_DETECT_RULES,
diff -Nru suricata-3.2/src/suricata.h suricata-3.2.1/src/suricata.h
--- suricata-3.2/src/suricata.h 2016-11-29 18:16:48.000000000 +0100
+++ suricata-3.2.1/src/suricata.h 2017-02-15 08:54:17.000000000 +0100
@@ -71,7 +71,7 @@
/* the name of our binary */
#define PROG_NAME "Suricata"
-#define PROG_VER "3.2"
+#define PROG_VER "3.2.1"
/* workaround SPlint error (don't know __gnuc_va_list) */
#ifdef S_SPLINT_S
@@ -169,7 +169,7 @@
/* memset to zeros, and mutex init! */
-void GlobalInits();
+void GlobalsInitPreConfig();
extern volatile uint8_t suricata_ctl_flags;
@@ -195,5 +195,9 @@
extern int run_mode;
+void PreRunInit(const int runmode);
+void PreRunPostPrivsDropInit(const int runmode);
+void PostRunDeinit(const int runmode, struct timeval *start_time);
+
#endif /* __SURICATA_H__ */
diff -Nru suricata-3.2/src/tm-threads.c suricata-3.2.1/src/tm-threads.c
--- suricata-3.2/src/tm-threads.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/tm-threads.c 2017-02-15 08:54:12.000000000 +0100
@@ -1521,6 +1521,64 @@
return;
}
+/** \internal
+ *
+ * \brief make sure that all packet threads are done processing their
+ * in-flight packets
+ */
+static void TmThreadDrainPacketThreads(void)
+{
+ /* value in seconds */
+#define THREAD_KILL_MAX_WAIT_TIME 60
+ /* value in microseconds */
+#define WAIT_TIME 1000
+
+ uint64_t total_wait_time = 0;
+
+ ThreadVars *tv = NULL;
+
+again:
+ if (total_wait_time > (THREAD_KILL_MAX_WAIT_TIME * 1000000)) {
+ SCLogWarning(SC_ERR_SHUTDOWN, "unable to get all packet threads "
+ "to process their packets in time");
+ return;
+ }
+
+ SCMutexLock(&tv_root_lock);
+
+ /* all receive threads are part of packet processing threads */
+ tv = tv_root[TVT_PPT];
+
+ while (tv) {
+ if (tv->inq != NULL) {
+ /* we wait till we dry out all the inq packets, before we
+ * kill this thread. Do note that you should have disabled
+ * packet acquire by now using TmThreadDisableReceiveThreads()*/
+ if (!(strlen(tv->inq->name) == strlen("packetpool") &&
+ strcasecmp(tv->inq->name, "packetpool") == 0)) {
+ PacketQueue *q = &trans_q[tv->inq->id];
+ if (q->len != 0) {
+ SCMutexUnlock(&tv_root_lock);
+
+ total_wait_time += WAIT_TIME;
+
+ /* don't sleep while holding a lock */
+ usleep(WAIT_TIME);
+ goto again;
+ }
+ }
+ }
+
+ tv = tv->next;
+ }
+
+ SCMutexUnlock(&tv_root_lock);
+ return;
+
+#undef THREAD_KILL_MAX_WAIT_TIME
+#undef WAIT_TIME
+}
+
/**
* \brief Disable all threads having the specified TMs.
*
@@ -1618,6 +1676,11 @@
SCMutexUnlock(&tv_root_lock);
+ /* finally wait for all packet threads to have
+ * processed all of their 'live' packets so we
+ * don't process the last live packets together
+ * with FFR packets */
+ TmThreadDrainPacketThreads();
return;
}
@@ -1635,6 +1698,8 @@
ThreadVars *tv = NULL;
+ /* first drain all packet threads of their packets */
+ TmThreadDrainPacketThreads();
again:
SCMutexLock(&tv_root_lock);
diff -Nru suricata-3.2/src/unix-manager.c suricata-3.2.1/src/unix-manager.c
--- suricata-3.2/src/unix-manager.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/unix-manager.c 2017-02-15 08:54:12.000000000 +0100
@@ -31,8 +31,8 @@
#include "util-privs.h"
#include "util-debug.h"
+#include "util-device.h"
#include "util-signal.h"
-
#include "util-buffer.h"
#include <sys/un.h>
@@ -97,7 +97,7 @@
int len;
int ret;
int on = 1;
- char *sockettarget = NULL;
+ char sockettarget[PATH_MAX];
char *socketname;
this->start_timestamp = time(NULL);
@@ -108,42 +108,39 @@
TAILQ_INIT(&this->tasks);
TAILQ_INIT(&this->clients);
+ int check_dir = 0;
if (ConfGet("unix-command.filename", &socketname) == 1) {
if (PathIsAbsolute(socketname)) {
- sockettarget = SCStrdup(socketname);
- if (unlikely(sockettarget == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate socket name");
- return 0;
- }
+ strlcpy(sockettarget, socketname, sizeof(sockettarget));
} else {
- int socketlen = strlen(SOCKET_PATH) + strlen(socketname) + 2;
- sockettarget = SCMalloc(socketlen);
- if (unlikely(sockettarget == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate socket name");
- return 0;
- }
- snprintf(sockettarget, socketlen, "%s/%s", SOCKET_PATH, socketname);
+ snprintf(sockettarget, sizeof(sockettarget), "%s/%s",
+ SOCKET_PATH, socketname);
+ check_dir = 1;
+ }
+ } else {
+ strlcpy(sockettarget, SOCKET_TARGET, sizeof(sockettarget));
+ check_dir = 1;
+ }
+ SCLogInfo("Using unix socket file '%s'", sockettarget);
- /* Create socket dir */
+ if (check_dir) {
+ struct stat stat_buf;
+ /* coverity[toctou] */
+ if (stat(SOCKET_PATH, &stat_buf) != 0) {
+ /* coverity[toctou] */
ret = mkdir(SOCKET_PATH, S_IRWXU|S_IXGRP|S_IRGRP);
- if ( ret != 0 ) {
+ if (ret != 0) {
int err = errno;
if (err != EEXIST) {
- SCFree(sockettarget);
- SCLogError(SC_ERR_OPENING_FILE,
- "Cannot create socket directory %s: %s", SOCKET_PATH, strerror(err));
+ SCLogError(SC_ERR_INITIALIZATION,
+ "Cannot create socket directory %s: %s",
+ SOCKET_PATH, strerror(err));
return 0;
}
+ } else {
+ SCLogInfo("Created socket directory %s",
+ SOCKET_PATH);
}
-
- }
- SCLogInfo("Using unix socket file '%s'", sockettarget);
- }
- if (sockettarget == NULL) {
- sockettarget = SCStrdup(SOCKET_TARGET);
- if (unlikely(sockettarget == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate socket name");
- return 0;
}
}
@@ -162,7 +159,6 @@
SCLogWarning(SC_ERR_OPENING_FILE,
"Unix Socket: unable to create UNIX socket %s: %s",
addr.sun_path, strerror(errno));
- SCFree(sockettarget);
return 0;
}
this->select_max = this->socket + 1;
@@ -194,7 +190,6 @@
SCLogWarning(SC_ERR_INITIALIZATION,
"Unix socket: UNIX socket bind(%s) error: %s",
sockettarget, strerror(errno));
- SCFree(sockettarget);
return 0;
}
@@ -203,10 +198,8 @@
SCLogWarning(SC_ERR_INITIALIZATION,
"Command server: UNIX socket listen() error: %s",
strerror(errno));
- SCFree(sockettarget);
return 0;
}
- SCFree(sockettarget);
return 1;
}
@@ -908,16 +901,18 @@
if (UnixNew(&command) == 0) {
int failure_fatal = 0;
- SCLogError(SC_ERR_INITIALIZATION,
- "Unable to create unix command socket");
if (ConfGetBool("engine.init-failure-fatal", &failure_fatal) != 1) {
SCLogDebug("ConfGetBool could not load the value.");
}
SCFree(utd);
if (failure_fatal) {
+ SCLogError(SC_ERR_INITIALIZATION,
+ "Unable to create unix command socket");
exit(EXIT_FAILURE);
} else {
- return TM_ECODE_FAILED;
+ SCLogWarning(SC_ERR_INITIALIZATION,
+ "Unable to create unix command socket");
+ return TM_ECODE_OK;
}
}
@@ -1016,6 +1011,19 @@
return;
}
+// TODO can't think of a good name
+void UnixManagerThreadSpawnNonRunmode(void)
+{
+ /* Spawn the unix socket manager thread */
+ int unix_socket = ConfUnixSocketIsEnable();
+ if (unix_socket == 1) {
+ UnixManagerThreadSpawn(0);
+ UnixManagerRegisterCommand("iface-stat", LiveDeviceIfaceStat, NULL,
+ UNIX_CMD_TAKE_ARGS);
+ UnixManagerRegisterCommand("iface-list", LiveDeviceIfaceList, NULL, 0);
+ }
+}
+
/**
* \brief Used to kill unix manager thread(s).
*
@@ -1069,6 +1077,11 @@
{
return;
}
+
+void UnixManagerThreadSpawnNonRunmode(void)
+{
+ return;
+}
#endif /* BUILD_UNIX_SOCKET */
diff -Nru suricata-3.2/src/unix-manager.h suricata-3.2.1/src/unix-manager.h
--- suricata-3.2/src/unix-manager.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/unix-manager.h 2017-02-15 08:54:12.000000000 +0100
@@ -36,7 +36,6 @@
void UnixManagerThreadSpawn(int mode);
void UnixSocketKillSocketThread(void);
-
#ifdef BUILD_UNIX_SOCKET
TmEcode UnixManagerRegisterCommand(const char * keyword,
TmEcode (*Func)(json_t *, json_t *, void *),
@@ -47,5 +46,6 @@
#endif
void TmModuleUnixManagerRegister(void);
+void UnixManagerThreadSpawnNonRunmode(void);
#endif /* UNIX_MANAGER_H */
diff -Nru suricata-3.2/src/util-debug.c suricata-3.2.1/src/util-debug.c
--- suricata-3.2/src/util-debug.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-debug.c 2017-02-15 08:54:12.000000000 +0100
@@ -300,29 +300,19 @@
blue = "\x1b[34m";
reset = "\x1b[0m";
}
-
/* no of characters_written(cw) by snprintf */
int cw = 0;
- if (sc_log_module_initialized != 1) {
-#ifdef DEBUG
- printf("Logging module not initialized. Call SCLogInitLogModule(), "
- "before using the logging API\n");
-#endif
- return SC_ERR_LOG_MODULE_NOT_INIT;
- }
+ BUG_ON(sc_log_module_initialized != 1);
- char *temp_fmt = strdup(log_format);
- if (unlikely(temp_fmt == NULL)) {
- return SC_ERR_MEM_ALLOC;
- }
- char *temp_fmt_h = temp_fmt;
+ /* make a copy of the format string as it will be modified below */
+ char local_format[strlen(log_format) + 1];
+ strlcpy(local_format, log_format, sizeof(local_format));
+ char *temp_fmt = local_format;
char *substr = temp_fmt;
while ( (temp_fmt = index(temp_fmt, SC_LOG_FMT_PREFIX)) ) {
if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
return SC_OK;
}
switch(temp_fmt[1]) {
@@ -338,7 +328,7 @@
tms->tm_year + 1900, tms->tm_hour, tms->tm_min,
tms->tm_sec, reset);
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
@@ -350,7 +340,7 @@
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
"%s%s%u%s", substr, yellow, getpid(), reset);
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
@@ -362,12 +352,13 @@
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
"%s%s%lu%s", substr, yellow, SCGetThreadIdLong(), reset);
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
substr++;
break;
+
case SC_LOG_FMT_TM:
temp_fmt[0] = '\0';
/* disabled to prevent dead lock:
@@ -382,12 +373,13 @@
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
"%s%s", substr, "N/A");
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
substr++;
break;
+
case SC_LOG_FMT_LOG_LEVEL:
temp_fmt[0] = '\0';
s = SCMapEnumValueToName(log_level, sc_log_level_map);
@@ -409,7 +401,7 @@
"%s%s", substr, "INVALID");
}
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
@@ -421,7 +413,7 @@
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
"%s%s%s%s", substr, blue, file, reset);
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
@@ -433,7 +425,7 @@
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
"%s%s%u%s", substr, green, line, reset);
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
@@ -445,7 +437,7 @@
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
"%s%s%s%s", substr, green, function, reset);
if (cw < 0)
- goto error;
+ return SC_ERR_SPRINTF;
temp += cw;
temp_fmt++;
substr = temp_fmt;
@@ -456,29 +448,25 @@
temp_fmt++;
}
if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
return SC_OK;
}
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s", substr);
- if (cw < 0)
- goto error;
+ if (cw < 0) {
+ return SC_ERR_SPRINTF;
+ }
temp += cw;
if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
return SC_OK;
}
if (error_code != SC_OK) {
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
"[%sERRCODE%s: %s%s%s(%s%d%s)] - ", yellow, reset, red, SCErrorToString(error_code), reset, yellow, error_code, reset);
- if (cw < 0)
- goto error;
+ if (cw < 0) {
+ return SC_ERR_SPRINTF;
+ }
temp += cw;
if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
return SC_OK;
}
}
@@ -489,17 +477,14 @@
else if (log_level <= SC_LOG_NOTICE)
hi = yellow;
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s", hi, message, reset);
- if (cw < 0)
- goto error;
+ if (cw < 0) {
+ return SC_ERR_SPRINTF;
+ }
temp += cw;
if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
return SC_OK;
}
- SCFree(temp_fmt_h);
-
if (sc_log_config->op_filter_regex != NULL) {
#define MAX_SUBSTRINGS 30
int ov[MAX_SUBSTRINGS];
@@ -514,11 +499,6 @@
}
return SC_OK;
-
- error:
- if (temp_fmt_h != NULL)
- SCFree(temp_fmt_h);
- return SC_ERR_SPRINTF;
}
static void SCLogReopen(SCLogOPIfaceCtx *op_iface_ctx)
diff -Nru suricata-3.2/src/util-decode-mime.c suricata-3.2.1/src/util-decode-mime.c
--- suricata-3.2/src/util-decode-mime.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-decode-mime.c 2017-02-15 08:54:12.000000000 +0100
@@ -2645,11 +2645,11 @@
while (1) {
int done = 0;
- size_t result = fread(&buffer, 1, sizeof(buffer), fp);
- if (result < sizeof(buffer))
+ size_t size = fread(&buffer, 1, sizeof(buffer), fp);
+ if (size < sizeof(buffer))
done = 1;
- (void) MimeDecParseLine(buffer, result, 1, state);
+ (void) MimeDecParseLine(buffer, size, 1, state);
if (done)
break;
diff -Nru suricata-3.2/src/util-error.c suricata-3.2.1/src/util-error.c
--- suricata-3.2/src/util-error.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-error.c 2017-02-15 08:54:12.000000000 +0100
@@ -333,6 +333,8 @@
CASE_CODE (SC_ERR_DNP3_CONFIG);
CASE_CODE (SC_ERR_DIR_OPEN);
CASE_CODE(SC_WARN_REMOVE_FILE);
+ CASE_CODE (SC_ERR_NO_MAGIC_SUPPORT);
+ CASE_CODE (SC_ERR_REDIS);
}
return "UNKNOWN_ERROR";
diff -Nru suricata-3.2/src/util-error.h suricata-3.2.1/src/util-error.h
--- suricata-3.2/src/util-error.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-error.h 2017-02-15 08:54:12.000000000 +0100
@@ -323,6 +323,8 @@
SC_ERR_DNP3_CONFIG,
SC_ERR_DIR_OPEN,
SC_WARN_REMOVE_FILE,
+ SC_ERR_NO_MAGIC_SUPPORT,
+ SC_ERR_REDIS,
} SCError;
const char *SCErrorToString(SCError);
diff -Nru suricata-3.2/src/util-file.c suricata-3.2.1/src/util-file.c
--- suricata-3.2/src/util-file.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-file.c 2017-02-15 08:54:12.000000000 +0100
@@ -267,12 +267,12 @@
}
/**
- * \brief get the size of the file
+ * \brief get the size of the file data
*
* This doesn't reflect how much of the file we have in memory, just the
- * total size tracked so far.
+ * total size of filedata so far.
*/
-uint64_t FileSize(const File *file)
+uint64_t FileDataSize(const File *file)
{
if (file != NULL && file->sb != NULL) {
SCLogDebug("returning %"PRIu64,
@@ -283,10 +283,24 @@
return 0;
}
+/**
+ * \brief get the size of the file
+ *
+ * This doesn't reflect how much of the file we have in memory, just the
+ * total size of file so far.
+ */
+uint64_t FileTrackedSize(const File *file)
+{
+ if (file != NULL) {
+ return file->size;
+ }
+ return 0;
+}
+
static int FilePruneFile(File *file)
{
SCEnter();
-
+#ifdef HAVE_MAGIC
if (!(file->flags & FILE_NOMAGIC)) {
/* need magic but haven't set it yet, bail out */
if (file->magic == NULL)
@@ -296,10 +310,10 @@
} else {
SCLogDebug("file->flags & FILE_NOMAGIC == true");
}
-
+#endif
uint64_t left_edge = file->content_stored;
if (file->flags & FILE_NOSTORE) {
- left_edge = FileSize(file);
+ left_edge = FileDataSize(file);
}
if (file->flags & FILE_USE_DETECT) {
left_edge = MIN(left_edge, file->content_inspected);
@@ -309,7 +323,7 @@
StreamingBufferSlideToOffset(file->sb, left_edge);
}
- if (left_edge != FileSize(file)) {
+ if (left_edge != FileDataSize(file)) {
SCReturnInt(0);
}
@@ -443,11 +457,11 @@
if (ff->name != NULL)
SCFree(ff->name);
-
+#ifdef HAVE_MAGIC
/* magic returned by libmagic is strdup'd by MagicLookup. */
if (ff->magic != NULL)
SCFree(ff->magic);
-
+#endif
if (ff->sb != NULL) {
StreamingBufferFree(ff->sb);
}
@@ -516,7 +530,7 @@
if (ff->flags & FILE_NOSTORE) {
if (ff->state == FILE_STATE_OPENED &&
- FileSize(ff) >= (uint64_t)FileMagicSize())
+ FileDataSize(ff) >= (uint64_t)FileMagicSize())
{
SCReturnInt(1);
}
@@ -565,6 +579,8 @@
SCReturnInt(-1);
}
+ ffc->tail->size += data_len;
+
if (ffc->tail->state != FILE_STATE_OPENED) {
if (ffc->tail->flags & FILE_NOSTORE) {
SCReturnInt(-2);
@@ -574,19 +590,23 @@
if (FileStoreNoStoreCheck(ffc->tail) == 1) {
#ifdef HAVE_NSS
+ int hash_done = 0;
/* no storage but forced hashing */
if (ffc->tail->md5_ctx) {
HASH_Update(ffc->tail->md5_ctx, data, data_len);
- SCReturnInt(0);
+ hash_done = 1;
}
if (ffc->tail->sha1_ctx) {
HASH_Update(ffc->tail->sha1_ctx, data, data_len);
- SCReturnInt(0);
+ hash_done = 1;
}
if (ffc->tail->sha256_ctx) {
HASH_Update(ffc->tail->sha256_ctx, data, data_len);
- SCReturnInt(0);
+ hash_done = 1;
}
+
+ if (hash_done)
+ SCReturnInt(0);
#endif
if (g_file_force_tracking || (!(ffc->tail->flags & FILE_NOTRACK)))
SCReturnInt(0);
@@ -695,11 +715,12 @@
FileContainerAdd(ffc, ff);
if (data != NULL) {
+ ff->size += data_len;
if (AppendData(ff, data, data_len) != 0) {
ff->state = FILE_STATE_ERROR;
SCReturnPtr(NULL, "File");
}
- SCLogDebug("file size is now %"PRIu64, FileSize(ff));
+ SCLogDebug("file size is now %"PRIu64, FileTrackedSize(ff));
}
SCReturnPtr(ff, "File");
@@ -719,6 +740,7 @@
}
if (data != NULL) {
+ ff->size += data_len;
if (ff->flags & FILE_NOSTORE) {
#ifdef HAVE_NSS
/* no storage but hashing */
@@ -1026,7 +1048,7 @@
SCLogDebug("not storing this file");
ff->flags |= FILE_NOSTORE;
- if (ff->state == FILE_STATE_OPENED && FileSize(ff) >= (uint64_t)FileMagicSize()) {
+ if (ff->state == FILE_STATE_OPENED && FileDataSize(ff) >= (uint64_t)FileMagicSize()) {
if (g_file_force_md5 == 0 && g_file_force_sha1 == 0 && g_file_force_sha256 == 0
&& g_file_force_tracking == 0) {
(void)FileCloseFilePtr(ff, NULL, 0,
diff -Nru suricata-3.2/src/util-file.h suricata-3.2.1/src/util-file.h
--- suricata-3.2/src/util-file.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-file.h 2017-02-15 08:54:12.000000000 +0100
@@ -67,7 +67,9 @@
uint64_t txid; /**< tx this file is part of */
uint32_t file_id;
uint8_t *name;
+#ifdef HAVE_MAGIC
char *magic;
+#endif
struct File_ *next;
#ifdef HAVE_NSS
HASHContext *md5_ctx;
@@ -80,6 +82,7 @@
uint64_t content_inspected; /**< used in pruning if FILE_USE_DETECT
* flag is set */
uint64_t content_stored;
+ uint64_t size;
} File;
typedef struct FileContainer_ {
@@ -211,7 +214,8 @@
void FileTruncateAllOpenFiles(FileContainer *);
-uint64_t FileSize(const File *file);
+uint64_t FileDataSize(const File *file);
+uint64_t FileTrackedSize(const File *file);
uint16_t FileFlowToFlags(const Flow *flow, uint8_t direction);
diff -Nru suricata-3.2/src/util-logopenfile.c suricata-3.2.1/src/util-logopenfile.c
--- suricata-3.2/src/util-logopenfile.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-logopenfile.c 2017-02-15 08:54:12.000000000 +0100
@@ -280,6 +280,15 @@
log_ctx->pcie_fp = SCLogOpenPcieFp(log_ctx, log_path, append);
if (log_ctx->pcie_fp == NULL)
return -1; // Error already logged by Open...Fp routine
+#ifdef HAVE_LIBHIREDIS
+ } else if (strcasecmp(filetype, "redis") == 0) {
+ ConfNode *redis_node = ConfNodeLookupChild(conf, "redis");
+ if (SCConfLogOpenRedis(redis_node, log_ctx) < 0) {
+ SCLogError(SC_ERR_REDIS, "failed to open redis output");
+ return -1;
+ }
+ log_ctx->type = LOGFILE_TYPE_REDIS;
+#endif
} else {
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for "
"%s.filetype. Expected \"regular\" (default), \"unix_stream\", "
@@ -592,10 +601,10 @@
file_ctx->redis_setup.batch_count++;
}
} else {
- redisReply *reply = redisCommand(file_ctx->redis, "%s %s %s",
+ redisReply *reply = redisCommand(file_ctx->redis, "%s %s %b",
file_ctx->redis_setup.command,
file_ctx->redis_setup.key,
- string);
+ string, string_len);
/* We may lose the reply if disconnection happens! */
if (reply) {
diff -Nru suricata-3.2/src/util-lua-common.c suricata-3.2.1/src/util-lua-common.c
--- suricata-3.2/src/util-lua-common.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-lua-common.c 2017-02-15 08:54:12.000000000 +0100
@@ -248,6 +248,37 @@
}
/** \internal
+ * \brief fill lua stack with flow has alerts
+ * \param luastate the lua state
+ * \param flow flow
+ * \retval cnt number of data items placed on the stack
+ *
+ * Places alerts (bool)
+ */
+static int LuaCallbackHasAlertsPushToStackFromFlow(lua_State *luastate, const Flow *flow)
+{
+ lua_pushboolean(luastate, FlowHasAlerts(flow));
+
+ return 1;
+}
+
+/** \internal
+ * \brief Wrapper for getting flow has alerts info into a lua script
+ * \retval cnt number of items placed on the stack
+ */
+static int LuaCallbackFlowHasAlerts(lua_State *luastate)
+{
+ int r = 0;
+ Flow *flow = LuaStateGetFlow(luastate);
+ if (flow == NULL)
+ return LuaCallbackError(luastate, "internal error: no flow");
+
+ r = LuaCallbackHasAlertsPushToStackFromFlow(luastate, flow);
+
+ return r;
+}
+
+/** \internal
* \brief fill lua stack with header info
* \param luastate the lua state
* \param p packet
@@ -650,8 +681,14 @@
lua_pushnumber(luastate, file->file_id);
lua_pushnumber(luastate, file->txid);
lua_pushlstring(luastate, (char *)file->name, file->name_len);
- lua_pushnumber(luastate, FileSize(file));
- lua_pushstring (luastate, file->magic);
+ lua_pushnumber(luastate, FileTrackedSize(file));
+ lua_pushstring (luastate,
+#ifdef HAVE_MAGIC
+ file->magic
+#else
+ "nomagic"
+#endif
+ );
lua_pushstring(luastate, md5ptr);
lua_pushstring(luastate, sha1ptr);
lua_pushstring(luastate, sha256ptr);
@@ -762,6 +799,8 @@
lua_setglobal(luastate, "SCFlowAppLayerProto");
lua_pushcfunction(luastate, LuaCallbackStatsFlow);
lua_setglobal(luastate, "SCFlowStats");
+ lua_pushcfunction(luastate, LuaCallbackFlowHasAlerts);
+ lua_setglobal(luastate, "SCFlowHasAlerts");
lua_pushcfunction(luastate, LuaCallbackStreamingBuffer);
lua_setglobal(luastate, "SCStreamingBuffer");
diff -Nru suricata-3.2/src/util-lua-dns.c suricata-3.2.1/src/util-lua-dns.c
--- suricata-3.2/src/util-lua-dns.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-lua-dns.c 2017-02-15 08:54:12.000000000 +0100
@@ -214,13 +214,17 @@
ptr = (uint8_t *)((uint8_t *)answer + sizeof(DNSAnswerEntry) + answer->fqdn_len);
if (answer->type == DNS_RECORD_TYPE_A) {
char a[16] = "";
- PrintInet(AF_INET, (const void *)ptr, a, sizeof(a));
+ if (answer->data_len == 4) {
+ PrintInet(AF_INET, (const void *)ptr, a, sizeof(a));
+ }
lua_pushstring(luastate, "addr");
LuaPushStringBuffer(luastate, (uint8_t *)a, strlen(a));
lua_settable(luastate, -3);
} else if (answer->type == DNS_RECORD_TYPE_AAAA) {
- char a[46];
- PrintInet(AF_INET6, (const void *)ptr, a, sizeof(a));
+ char a[46] = "";
+ if (answer->data_len == 16) {
+ PrintInet(AF_INET6, (const void *)ptr, a, sizeof(a));
+ }
lua_pushstring(luastate, "addr");
LuaPushStringBuffer(luastate, (uint8_t *)a, strlen(a));
lua_settable(luastate, -3);
diff -Nru suricata-3.2/src/util-magic.c suricata-3.2.1/src/util-magic.c
--- suricata-3.2/src/util-magic.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-magic.c 2017-02-15 08:54:12.000000000 +0100
@@ -28,10 +28,11 @@
*/
#include "suricata-common.h"
+
+#ifdef HAVE_MAGIC
#include "conf.h"
#include "util-unittest.h"
-#include <magic.h>
static magic_t g_magic_ctx = NULL;
static SCMutex g_magic_lock;
@@ -654,10 +655,11 @@
}
#endif /* UNITTESTS */
-
+#endif
void MagicRegisterTests(void)
{
+#ifdef HAVE_MAGIC
#ifdef UNITTESTS
UtRegisterTest("MagicInitTest01", MagicInitTest01);
UtRegisterTest("MagicInitTest02", MagicInitTest02);
@@ -675,4 +677,6 @@
UtRegisterTest("MagicDetectTest10ValgrindError",
MagicDetectTest10ValgrindError);
#endif /* UNITTESTS */
+#endif /* HAVE_MAGIC */
}
+
diff -Nru suricata-3.2/src/util-magic.h suricata-3.2.1/src/util-magic.h
--- suricata-3.2/src/util-magic.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-magic.h 2017-02-15 08:54:12.000000000 +0100
@@ -24,12 +24,12 @@
#ifndef __UTIL_MAGIC_H__
#define __UTIL_MAGIC_H__
-#include <magic.h>
-
+#ifdef HAVE_MAGIC
int MagicInit(void);
void MagicDeinit(void);
char *MagicGlobalLookup(const uint8_t *, uint32_t);
char *MagicThreadLookup(magic_t *, const uint8_t *, uint32_t);
+#endif
void MagicRegisterTests(void);
#endif /* __UTIL_MAGIC_H__ */
diff -Nru suricata-3.2/src/util-mpm-ac-bs.c suricata-3.2.1/src/util-mpm-ac-bs.c
--- suricata-3.2/src/util-mpm-ac-bs.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-mpm-ac-bs.c 2017-02-15 08:54:12.000000000 +0100
@@ -719,7 +719,6 @@
uint16_t *curr_loc = (uint16_t *)ctx->state_table_mod;
uint16_t *no_of_entries = NULL;
uint16_t *ascii_codes = NULL;
- state = 0;
uint16_t ascii_code = 0;
uint16_t k = 0;
for (state = 0; state < ctx->state_count; state++) {
@@ -794,7 +793,6 @@
uint32_t *curr_loc = (uint32_t *)ctx->state_table_mod;
uint32_t *no_of_entries = NULL;
uint32_t *ascii_codes = NULL;
- state = 0;
uint32_t ascii_code = 0;
uint32_t k = 0;
for (state = 0; state < ctx->state_count; state++) {
@@ -1192,7 +1190,6 @@
int low = 0;
int high = no_of_entries;
int mid;
- state = 0;
while (low <= high) {
mid = (low + high) / 2;
if (ascii_codes[mid] == buf_local) {
@@ -1276,7 +1273,6 @@
int low = 0;
int high = no_of_entries;
int mid;
- state = 0;
while (low <= high) {
mid = (low + high) / 2;
if (ascii_codes[mid] == buf_local) {
diff -Nru suricata-3.2/src/util-mpm-ac.c suricata-3.2.1/src/util-mpm-ac.c
--- suricata-3.2/src/util-mpm-ac.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-mpm-ac.c 2017-02-15 08:54:12.000000000 +0100
@@ -122,6 +122,28 @@
/**
* \internal
+ * \brief Check if size_t multiplication would overflow and perform operation
+ * if safe. In case of an overflow we exit().
+ *
+ * \param a First size_t value to multiplicate.
+ * \param b Second size_t value to multiplicate.
+ *
+ * \retval The product of a and b, guaranteed to not overflow.
+ */
+static inline size_t SCACCheckSafeSizetMult(size_t a, size_t b)
+{
+ /* check for safety of multiplication operation */
+ if (b > 0 && a > SIZE_MAX / b) {
+ SCLogError(SC_ERR_MEM_ALLOC, "%"PRIuMAX" * %"PRIuMAX" > %"
+ PRIuMAX" would overflow size_t calculating buffer size",
+ (uintmax_t) a, (uintmax_t) b, (uintmax_t) SIZE_MAX);
+ exit(EXIT_FAILURE);
+ }
+ return a * b;
+}
+
+/**
+ * \internal
* \brief Initialize a new state in the goto and output tables.
*
* \param mpm_ctx Pointer to the mpm context.
@@ -130,12 +152,13 @@
*/
static inline int SCACReallocState(SCACCtx *ctx, uint32_t cnt)
{
- void *ptmp;
- int size = 0;
+ void *ptmp = NULL;
+ size_t size = 0;
/* reallocate space in the goto table to include a new state */
- size = cnt * ctx->single_state_size;
- ptmp = SCRealloc(ctx->goto_table, size);
+ size = SCACCheckSafeSizetMult((size_t) cnt, (size_t) ctx->single_state_size);
+ if (size > 0)
+ ptmp = SCRealloc(ctx->goto_table, size);
if (ptmp == NULL) {
SCFree(ctx->goto_table);
ctx->goto_table = NULL;
@@ -145,12 +168,15 @@
ctx->goto_table = ptmp;
/* reallocate space in the output table for the new state */
- int oldsize = ctx->state_count * sizeof(SCACOutputTable);
- size = cnt * sizeof(SCACOutputTable);
- SCLogDebug("oldsize %d size %d cnt %u ctx->state_count %u",
- oldsize, size, cnt, ctx->state_count);
+ size_t oldsize = SCACCheckSafeSizetMult((size_t) ctx->state_count,
+ sizeof(SCACOutputTable));
+ size = SCACCheckSafeSizetMult((size_t) cnt, sizeof(SCACOutputTable));
+ SCLogDebug("oldsize %"PRIuMAX" size %"PRIuMAX" cnt %d ctx->state_count %u",
+ (uintmax_t) oldsize, (uintmax_t) size, cnt, ctx->state_count);
- ptmp = SCRealloc(ctx->output_table, size);
+ ptmp = NULL;
+ if (size > 0)
+ ptmp = SCRealloc(ctx->output_table, size);
if (ptmp == NULL) {
SCFree(ctx->output_table);
ctx->output_table = NULL;
diff -Nru suricata-3.2/src/util-mpm.c suricata-3.2.1/src/util-mpm.c
--- suricata-3.2/src/util-mpm.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-mpm.c 2017-02-15 08:54:12.000000000 +0100
@@ -46,6 +46,9 @@
#include "detect-engine-mpm.h"
#endif
#include "util-memcpy.h"
+#ifdef BUILD_HYPERSCAN
+#include "hs.h"
+#endif
/**
* \brief Register a new Mpm Context.
@@ -402,15 +405,46 @@
mpm_table[matcher].InitCtx(mpm_ctx);
}
+/* MPM matcher to use by default, i.e. when "mpm-algo" is set to "auto".
+ * If Hyperscan is available, use it. Otherwise, use AC. */
+#ifdef BUILD_HYPERSCAN
+# define DEFAULT_MPM MPM_HS
+# ifdef __tile__
+# define DEFAULT_MPM_AC MPM_AC_TILE
+# else
+# define DEFAULT_MPM_AC MPM_AC
+# endif
+#else
+# ifdef __tile__
+# define DEFAULT_MPM MPM_AC_TILE
+# else
+# define DEFAULT_MPM MPM_AC
+# endif
+#endif
+
void MpmTableSetup(void)
{
memset(mpm_table, 0, sizeof(mpm_table));
+ mpm_default_matcher = DEFAULT_MPM;
MpmACRegister();
MpmACBSRegister();
MpmACTileRegister();
#ifdef BUILD_HYPERSCAN
- MpmHSRegister();
+ #ifdef HAVE_HS_VALID_PLATFORM
+ /* Enable runtime check for SSSE3. Do not use Hyperscan MPM matcher if
+ * check is not successful. */
+ if (hs_valid_platform() != HS_SUCCESS) {
+ SCLogInfo("SSSE3 support not detected, disabling Hyperscan for "
+ "MPM");
+ /* Fall back to best Aho-Corasick variant. */
+ mpm_default_matcher = DEFAULT_MPM_AC;
+ } else {
+ MpmHSRegister();
+ }
+ #else
+ MpmHSRegister();
+ #endif /* HAVE_HS_VALID_PLATFORM */
#endif /* BUILD_HYPERSCAN */
#ifdef __SC_CUDA_SUPPORT__
MpmACCudaRegister();
diff -Nru suricata-3.2/src/util-mpm.h suricata-3.2.1/src/util-mpm.h
--- suricata-3.2/src/util-mpm.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-mpm.h 2017-02-15 08:54:12.000000000 +0100
@@ -43,18 +43,6 @@
MPM_TABLE_SIZE,
};
-/* MPM matcher to use by default, i.e. when "mpm-algo" is set to "auto".
- * If Hyperscan is available, use it. Otherwise, use AC. */
-#ifdef BUILD_HYPERSCAN
-# define DEFAULT_MPM MPM_HS
-#else
-# ifdef __tile__
-# define DEFAULT_MPM MPM_AC_TILE
-# else
-# define DEFAULT_MPM MPM_AC
-# endif
-#endif
-
/* Internal Pattern Index: 0 to pattern_cnt-1 */
typedef uint32_t MpmPatternIndex;
@@ -171,6 +159,7 @@
} MpmTableElmt;
MpmTableElmt mpm_table[MPM_TABLE_SIZE];
+int mpm_default_matcher;
/* macros decides if cuda is enabled for the platform or not */
#ifdef __SC_CUDA_SUPPORT__
diff -Nru suricata-3.2/src/util-mpm-hs.c suricata-3.2.1/src/util-mpm-hs.c
--- suricata-3.2/src/util-mpm-hs.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-mpm-hs.c 2017-02-15 08:54:12.000000000 +0100
@@ -657,6 +657,7 @@
if (p->flags & (MPM_PATTERN_FLAG_OFFSET | MPM_PATTERN_FLAG_DEPTH)) {
cd->ext[i] = SCMalloc(sizeof(hs_expr_ext_t));
if (cd->ext[i] == NULL) {
+ SCMutexUnlock(&g_db_table_mutex);
goto error;
}
memset(cd->ext[i], 0, sizeof(hs_expr_ext_t));
@@ -685,6 +686,7 @@
SCLogError(SC_ERR_FATAL, "compile error: %s", compile_err->message);
}
hs_free_compile_error(compile_err);
+ SCMutexUnlock(&g_db_table_mutex);
goto error;
}
@@ -695,12 +697,14 @@
SCMutexUnlock(&g_scratch_proto_mutex);
if (err != HS_SUCCESS) {
SCLogError(SC_ERR_FATAL, "failed to allocate scratch");
+ SCMutexUnlock(&g_db_table_mutex);
goto error;
}
err = hs_database_size(pd->hs_db, &ctx->hs_db_size);
if (err != HS_SUCCESS) {
SCLogError(SC_ERR_FATAL, "failed to query database size");
+ SCMutexUnlock(&g_db_table_mutex);
goto error;
}
@@ -719,7 +723,6 @@
return 0;
error:
- SCMutexUnlock(&g_db_table_mutex);
if (pd) {
PatternDatabaseFree(pd);
}
diff -Nru suricata-3.2/src/util-privs.c suricata-3.2.1/src/util-privs.c
--- suricata-3.2/src/util-privs.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-privs.c 2017-02-15 08:54:12.000000000 +0100
@@ -77,6 +77,7 @@
capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
CAP_NET_RAW, /* needed for pcap live mode */
CAP_SYS_NICE,
+ CAP_NET_ADMIN,
-1);
break;
case RUNMODE_PFRING:
diff -Nru suricata-3.2/src/util-profiling.c suricata-3.2.1/src/util-profiling.c
--- suricata-3.2/src/util-profiling.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-profiling.c 2017-02-15 08:54:12.000000000 +0100
@@ -102,14 +102,14 @@
struct ProfileProtoRecords packet_profile_flowworker_data[PROFILE_FLOWWORKER_SIZE];
int profiling_packets_enabled = 0;
-int profiling_packets_csv_enabled = 0;
-
int profiling_output_to_file = 0;
-int profiling_packets_output_to_file = 0;
-char *profiling_file_name;
-char *profiling_packets_file_name;
-char *profiling_csv_file_name;
-const char *profiling_packets_file_mode = "a";
+
+static int profiling_packets_csv_enabled = 0;
+static int profiling_packets_output_to_file = 0;
+static char *profiling_file_name;
+static char profiling_packets_file_name[PATH_MAX];
+static char *profiling_csv_file_name;
+static const char *profiling_packets_file_mode = "a";
static int rate = 1;
static SC_ATOMIC_DECLARE(uint64_t, samples);
@@ -187,13 +187,8 @@
char *log_dir;
log_dir = ConfigGetLogDirectory();
- profiling_packets_file_name = SCMalloc(PATH_MAX);
- if (unlikely(profiling_packets_file_name == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
- exit(EXIT_FAILURE);
- }
-
- snprintf(profiling_packets_file_name, PATH_MAX, "%s/%s", log_dir, filename);
+ snprintf(profiling_packets_file_name, sizeof(profiling_packets_file_name),
+ "%s/%s", log_dir, filename);
const char *v = ConfNodeLookupChildValue(conf, "append");
if (v == NULL || ConfValIsTrue(v)) {
@@ -1117,7 +1112,7 @@
}
static void SCProfilingUpdatePacketGenericRecords(Packet *p, PktProfilingData *pd,
- struct ProfileProtoRecords *store, int size)
+ struct ProfileProtoRecords *records, int size)
{
int i;
for (i = 0; i < size; i++) {
@@ -1127,7 +1122,7 @@
continue;
}
- struct ProfileProtoRecords *r = &store[i];
+ struct ProfileProtoRecords *r = &records[i];
SCProfilePacketData *store = NULL;
if (PKT_IS_IPV4(p)) {
diff -Nru suricata-3.2/src/util-profiling-keywords.c suricata-3.2.1/src/util-profiling-keywords.c
--- suricata-3.2/src/util-profiling-keywords.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-profiling-keywords.c 2017-02-15 08:54:12.000000000 +0100
@@ -63,7 +63,7 @@
static int profiling_keywords_output_to_file = 0;
int profiling_keyword_enabled = 0;
__thread int profiling_keyword_entered = 0;
-static char *profiling_file_name = "";
+static char profiling_file_name[PATH_MAX];
static const char *profiling_file_mode = "a";
void SCProfilingKeywordsGlobalInit(void)
@@ -80,12 +80,8 @@
char *log_dir;
log_dir = ConfigGetLogDirectory();
- profiling_file_name = SCMalloc(PATH_MAX);
- if (unlikely(profiling_file_name == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
- exit(EXIT_FAILURE);
- }
- snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename);
+ snprintf(profiling_file_name, sizeof(profiling_file_name), "%s/%s",
+ log_dir, filename);
const char *v = ConfNodeLookupChildValue(conf, "append");
if (v == NULL || ConfValIsTrue(v)) {
diff -Nru suricata-3.2/src/util-profiling-rulegroups.c suricata-3.2.1/src/util-profiling-rulegroups.c
--- suricata-3.2/src/util-profiling-rulegroups.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-profiling-rulegroups.c 2017-02-15 08:54:12.000000000 +0100
@@ -64,7 +64,7 @@
static int profiling_sghs_output_to_file = 0;
int profiling_sghs_enabled = 0;
-static char *profiling_file_name = "";
+static char profiling_file_name[PATH_MAX];
static const char *profiling_file_mode = "a";
#ifdef HAVE_LIBJANSSON
static int profiling_rulegroup_json = 0;
@@ -84,12 +84,8 @@
char *log_dir;
log_dir = ConfigGetLogDirectory();
- profiling_file_name = SCMalloc(PATH_MAX);
- if (unlikely(profiling_file_name == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
- exit(EXIT_FAILURE);
- }
- snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename);
+ snprintf(profiling_file_name, sizeof(profiling_file_name),
+ "%s/%s", log_dir, filename);
const char *v = ConfNodeLookupChildValue(conf, "append");
if (v == NULL || ConfValIsTrue(v)) {
diff -Nru suricata-3.2/src/util-profiling-rules.c suricata-3.2.1/src/util-profiling-rules.c
--- suricata-3.2/src/util-profiling-rules.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-profiling-rules.c 2017-02-15 08:54:12.000000000 +0100
@@ -79,7 +79,7 @@
extern int profiling_output_to_file;
int profiling_rules_enabled = 0;
-static char *profiling_file_name = "";
+static char profiling_file_name[PATH_MAX] = "";
static const char *profiling_file_mode = "a";
#ifdef HAVE_LIBJANSSON
static int profiling_rule_json = 0;
@@ -165,12 +165,8 @@
char *log_dir;
log_dir = ConfigGetLogDirectory();
- profiling_file_name = SCMalloc(PATH_MAX);
- if (unlikely(profiling_file_name == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
- exit(EXIT_FAILURE);
- }
- snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename);
+ snprintf(profiling_file_name, sizeof(profiling_file_name),
+ "%s/%s", log_dir, filename);
const char *v = ConfNodeLookupChildValue(conf, "append");
if (v == NULL || ConfValIsTrue(v)) {
diff -Nru suricata-3.2/src/util-spm.c suricata-3.2.1/src/util-spm.c
--- suricata-3.2/src/util-spm.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-spm.c 2017-02-15 08:54:12.000000000 +0100
@@ -55,6 +55,9 @@
#include "util-spm-bm.h"
#include "util-spm-hs.h"
#include "util-clock.h"
+#ifdef BUILD_HYPERSCAN
+#include "hs.h"
+#endif
/**
* \brief Returns the single pattern matcher algorithm to be used, based on the
@@ -89,7 +92,20 @@
/* When Suricata is built with Hyperscan support, default to using it for
* SPM. */
#ifdef BUILD_HYPERSCAN
- return SPM_HS;
+ #ifdef HAVE_HS_VALID_PLATFORM
+ /* Enable runtime check for SSSE3. Do not use Hyperscan SPM matcher if
+ * check is not successful. */
+ if (hs_valid_platform() != HS_SUCCESS) {
+ SCLogInfo("SSSE3 support not detected, disabling Hyperscan for "
+ "SPM");
+ /* Use Boyer-Moore as fallback. */
+ return SPM_BM;
+ } else {
+ return SPM_HS;
+ }
+ #else
+ return SPM_HS;
+ #endif
#else
/* Otherwise, default to Boyer-Moore */
return SPM_BM;
@@ -102,7 +118,13 @@
SpmBMRegister();
#ifdef BUILD_HYPERSCAN
- SpmHSRegister();
+ #ifdef HAVE_HS_VALID_PLATFORM
+ if (hs_valid_platform() == HS_SUCCESS) {
+ SpmHSRegister();
+ }
+ #else
+ SpmHSRegister();
+ #endif
#endif
}
diff -Nru suricata-3.2/src/util-var.c suricata-3.2.1/src/util-var.c
--- suricata-3.2/src/util-var.c 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-var.c 2017-02-15 08:54:12.000000000 +0100
@@ -36,7 +36,7 @@
#include "util-debug.h"
-static void XBitFree(XBit *fb)
+void XBitFree(XBit *fb)
{
if (fb == NULL)
return;
diff -Nru suricata-3.2/src/util-var.h suricata-3.2.1/src/util-var.h
--- suricata-3.2/src/util-var.h 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/src/util-var.h 2017-02-15 08:54:12.000000000 +0100
@@ -57,6 +57,8 @@
uint32_t expire;
} XBit;
+void XBitFree(XBit *);
+
// A list of variables we try to resolve while parsing configuration file.
// Helps to detect recursive declarations.
typedef struct ResolvedVariable_ {
diff -Nru suricata-3.2/suricata.yaml.in suricata-3.2.1/suricata.yaml.in
--- suricata-3.2/suricata.yaml.in 2016-11-29 18:16:41.000000000 +0100
+++ suricata-3.2.1/suricata.yaml.in 2017-02-15 08:54:12.000000000 +0100
@@ -50,6 +50,7 @@
default-rule-path: @e_sysconfdir@rules
rule-files:
- botcc.rules
+ # - botcc.portgrouped.rules
- ciarmy.rules
- compromised.rules
- drop.rules
@@ -67,6 +68,7 @@
# - emerging-icmp.rules
- emerging-imap.rules
# - emerging-inappropriate.rules
+# - emerging-info.rules
- emerging-malware.rules
- emerging-misc.rules
- emerging-mobile_malware.rules
@@ -75,7 +77,8 @@
- emerging-policy.rules
- emerging-pop3.rules
- emerging-rpc.rules
- - emerging-scada.rules
+# - emerging-scada.rules
+# - emerging-scada_special.rules
- emerging-scan.rules
# - emerging-shellcode.rules
- emerging-smtp.rules
@@ -703,7 +706,7 @@
smb:
enabled: yes
detection-ports:
- dp: 139
+ dp: 139, 445
# smb2 detection is disabled internally inside the engine.
#smb2:
# enabled: yes
@@ -1217,7 +1220,9 @@
# prealloc: 512
# - size: 768
# prealloc: 1024
- # - size: 1448
+ # 'from_mtu' means that the size is mtu - 40,
+ # or 1460 if mtu couldn't be determined.
+ # - size: from_mtu
# prealloc: 1024
# - size: 65535
# prealloc: 128
Reply to: