From d2b7872b70b689fb2cf7f9803d33d75ca9a6752d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= Date: Wed, 20 Dec 2023 09:57:11 +0100 Subject: [PATCH] Fix test test_sysctl_probe_all.sh and clean up the repository --- 2015.patch | 2213 ----------------- ....3.10-fix_sysctl_probe_tests-PR-2050.patch | 165 ++ openscap.spec | 13 +- 3 files changed, 173 insertions(+), 2218 deletions(-) delete mode 100644 2015.patch create mode 100644 openscap-1.3.10-fix_sysctl_probe_tests-PR-2050.patch diff --git a/2015.patch b/2015.patch deleted file mode 100644 index 9a4f753..0000000 --- a/2015.patch +++ /dev/null @@ -1,2213 +0,0 @@ -From cd1d4289581fa15527e516ddd07be814af7cba55 Mon Sep 17 00:00:00 2001 -From: Evgeny Kolesnikov -Date: Mon, 28 Aug 2023 19:53:20 +0200 -Subject: [PATCH 1/4] Add PCRE2 library - -Recognize PCRE2 library in the build system. - -Add wrapper for pcre_/pcre2_ functions. ---- - CMakeLists.txt | 16 ++- - cmake/FindPCRE2.cmake | 27 +++++ - config.h.in | 2 + - src/CMakeLists.txt | 2 +- - src/common/oscap_pcre.c | 257 ++++++++++++++++++++++++++++++++++++++++ - src/common/oscap_pcre.h | 106 +++++++++++++++++ - 6 files changed, 408 insertions(+), 2 deletions(-) - create mode 100644 cmake/FindPCRE2.cmake - create mode 100644 src/common/oscap_pcre.c - create mode 100644 src/common/oscap_pcre.h - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 74628cdd466..b6e5a825dc1 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -106,7 +106,11 @@ find_package(Doxygen) - find_package(GConf) - find_package(Ldap) - find_package(OpenDbx) --find_package(PCRE REQUIRED) -+if(WITH_PCRE2) -+ find_package(PCRE2 REQUIRED) -+else() -+ find_package(PCRE REQUIRED) -+endif() - find_package(PerlLibs) - find_package(Popt) - find_package(Systemd) -@@ -193,6 +197,13 @@ else() - set(YAML_FILTER_FOUND FALSE) - endif() - -+if(PCRE2_FOUND) -+ set(HAVE_PCRE2 1) -+ message("-- Using PCRE2") -+elseif(PCRE_FOUND) -+ message("-- Using PCRE") -+endif() -+ - check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME) - check_function_exists(posix_memalign HAVE_POSIX_MEMALIGN) - check_function_exists(memalign HAVE_MEMALIGN) -@@ -330,6 +341,8 @@ cmake_dependent_option(ENABLE_OSCAP_UTIL_CHROOT "enables the oscap-chroot utilit - option(ENABLE_OSCAP_UTIL_AUTOTAILOR "enables the autotailor utility that is able to perform command-line tailoring" TRUE) - option(ENABLE_OSCAP_REMEDIATE_SERVICE "enables the oscap-remediate service" FALSE) - -+option(WITH_PCRE2 "use PCRE2 library" FALSE) -+ - # ---------- TEST-SUITE SWITCHES - - # Tests will be turned off on Windows, because the test suite uses bash -@@ -563,6 +576,7 @@ include_directories( - ${XMLSEC_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIR} - ${PCRE_INCLUDE_DIRS} -+ ${PCRE2_INCLUDE_DIRS} - ) - - # Honor visibility properties for all target types -diff --git a/cmake/FindPCRE2.cmake b/cmake/FindPCRE2.cmake -new file mode 100644 -index 00000000000..0c430b1fd22 ---- /dev/null -+++ b/cmake/FindPCRE2.cmake -@@ -0,0 +1,27 @@ -+# - Find pcre -+# Find the native PCRE2 headers and libraries. -+# -+# PCRE2_INCLUDE_DIRS - where to find pcre2.h, etc. -+# PCRE2_LIBRARIES - List of libraries when using pcre. -+# PCRE2_FOUND - True if pcre found. -+ -+# Look for the header file. -+FIND_PATH(PCRE2_INCLUDE_DIR pcre2.h) -+ -+# Look for the library. -+FIND_LIBRARY(PCRE2_LIBRARY NAMES libpcre2.a pcre2-8) -+ -+# Handle the QUIETLY and REQUIRED arguments and set PCRE2_FOUND to TRUE if all listed variables are TRUE. -+INCLUDE(FindPackageHandleStandardArgs) -+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE2 DEFAULT_MSG PCRE2_LIBRARY PCRE2_INCLUDE_DIR) -+ -+# Copy the results to the output variables. -+IF(PCRE2_FOUND) -+ SET(PCRE2_LIBRARIES ${PCRE2_LIBRARY}) -+ SET(PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR}) -+ELSE(PCRE2_FOUND) -+ SET(PCRE_LIBRARIES) -+ SET(PCRE_INCLUDE_DIRS) -+ENDIF(PCRE2_FOUND) -+ -+MARK_AS_ADVANCED(PCRE2_INCLUDE_DIRS PCRE2_LIBRARIES) -diff --git a/config.h.in b/config.h.in -index db8afd91410..2bba00719c2 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -29,6 +29,8 @@ - #define OSCAP_DEFAULT_CPE_PATH "@OSCAP_DEFAULT_CPE_PATH@" - #define OSCAP_TEMP_DIR "@OSCAP_TEMP_DIR@" - -+#cmakedefine HAVE_PCRE2 -+ - #cmakedefine HAVE_ATOMIC_BUILTINS - - #cmakedefine HAVE_ACL_EXTENDED_FILE -diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index e9339c62ed1..7fa94ff981f 100644 ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -81,7 +81,7 @@ set_target_properties(openscap PROPERTIES - C_VISIBILITY_PRESET hidden - ) - --target_link_libraries(openscap ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${XMLSEC_LIBRARIES} ${OPENSSL_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES} ${PCRE_LIBRARIES} ${CURL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -+target_link_libraries(openscap ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${XMLSEC_LIBRARIES} ${OPENSSL_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES} ${PCRE_LIBRARIES} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) - if (BZIP2_FOUND) - target_link_libraries(openscap ${BZIP2_LIBRARIES}) - endif() -diff --git a/src/common/oscap_pcre.c b/src/common/oscap_pcre.c -new file mode 100644 -index 00000000000..d2e45292ab1 ---- /dev/null -+++ b/src/common/oscap_pcre.c -@@ -0,0 +1,257 @@ -+/* -+ * Copyright 2023 Red Hat Inc., Durham, North Carolina. -+ * All Rights Reserved. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * Authors: -+ * Evgenii Kolesnikov -+ */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+ -+#ifdef HAVE_PCRE2 -+#define PCRE2_CODE_UNIT_WIDTH 8 -+#define PCRE2_ERR_BUF_SIZE 127 -+#include -+#else -+#include -+#endif -+ -+#include "debug_priv.h" -+#include "oscap_pcre.h" -+ -+ -+struct oscap_pcre { -+#ifdef HAVE_PCRE2 -+ pcre2_code_8 *re; -+ pcre2_match_context_8 *re_ctx; -+#else -+ pcre *re; -+ struct pcre_extra *re_extra; -+#endif -+}; -+ -+ -+static inline int _oscap_pcre_opts_to_pcre(oscap_pcre_options_t opts) -+{ -+ int res = 0; -+#ifdef HAVE_PCRE2 -+ if (opts & OSCAP_PCRE_OPTS_UTF8) -+ res |= PCRE2_UTF; -+ if (opts & OSCAP_PCRE_OPTS_MULTILINE) -+ res |= PCRE2_MULTILINE; -+ if (opts & OSCAP_PCRE_OPTS_DOTALL) -+ res |= PCRE2_DOTALL; -+ if (opts & OSCAP_PCRE_OPTS_CASELESS) -+ res |= PCRE2_CASELESS; -+ if (opts & OSCAP_PCRE_OPTS_NO_UTF8_CHECK) -+ res |= PCRE2_NO_UTF_CHECK; -+ if (opts & OSCAP_PCRE_OPTS_PARTIAL) -+ res |= PCRE2_PARTIAL_SOFT; -+#else -+ if (opts & OSCAP_PCRE_OPTS_UTF8) -+ res |= PCRE_UTF8; -+ if (opts & OSCAP_PCRE_OPTS_MULTILINE) -+ res |= PCRE_MULTILINE; -+ if (opts & OSCAP_PCRE_OPTS_DOTALL) -+ res |= PCRE_DOTALL; -+ if (opts & OSCAP_PCRE_OPTS_CASELESS) -+ res |= PCRE_CASELESS; -+ if (opts & OSCAP_PCRE_OPTS_NO_UTF8_CHECK) -+ res |= PCRE_NO_UTF8_CHECK; -+ if (opts & OSCAP_PCRE_OPTS_PARTIAL) -+ res |= PCRE_PARTIAL; -+#endif -+ return res; -+}; -+ -+static inline oscap_pcre_error_t _pcre_error_to_oscap_pcre(int res) -+{ -+ switch (res) { -+#ifdef HAVE_PCRE2 -+ case PCRE2_ERROR_NOMATCH: -+ return OSCAP_PCRE_ERR_NOMATCH; -+ case PCRE2_ERROR_PARTIAL: -+ return OSCAP_PCRE_ERR_PARTIAL; -+ case PCRE2_ERROR_UTF8_ERR1: -+ case PCRE2_ERROR_UTF8_ERR2: -+ case PCRE2_ERROR_UTF8_ERR3: -+ case PCRE2_ERROR_UTF8_ERR4: -+ case PCRE2_ERROR_UTF8_ERR5: -+ case PCRE2_ERROR_UTF8_ERR6: -+ case PCRE2_ERROR_UTF8_ERR7: -+ case PCRE2_ERROR_UTF8_ERR8: -+ case PCRE2_ERROR_UTF8_ERR9: -+ case PCRE2_ERROR_UTF8_ERR10: -+ case PCRE2_ERROR_UTF8_ERR11: -+ case PCRE2_ERROR_UTF8_ERR12: -+ case PCRE2_ERROR_UTF8_ERR13: -+ case PCRE2_ERROR_UTF8_ERR14: -+ case PCRE2_ERROR_UTF8_ERR15: -+ case PCRE2_ERROR_UTF8_ERR16: -+ case PCRE2_ERROR_UTF8_ERR17: -+ case PCRE2_ERROR_UTF8_ERR18: -+ case PCRE2_ERROR_UTF8_ERR19: -+ case PCRE2_ERROR_UTF8_ERR20: -+ case PCRE2_ERROR_UTF8_ERR21: -+ return OSCAP_PCRE_ERR_BADUTF8; -+ case PCRE2_ERROR_RECURSIONLIMIT: -+ return OSCAP_PCRE_ERR_RECURSIONLIMIT; -+#else -+ case PCRE_ERROR_NOMATCH: -+ return OSCAP_PCRE_ERR_NOMATCH; -+ case PCRE_ERROR_PARTIAL: -+ return OSCAP_PCRE_ERR_PARTIAL; -+ case PCRE_ERROR_BADPARTIAL: -+ return OSCAP_PCRE_ERR_BADPARTIAL; -+ case PCRE_ERROR_BADUTF8: -+ return OSCAP_PCRE_ERR_BADUTF8; -+ case PCRE_ERROR_RECURSIONLIMIT: -+ return OSCAP_PCRE_ERR_RECURSIONLIMIT; -+#endif -+ default: -+ dW("Unknown PCRE error code: %d", res); -+ return OSCAP_PCRE_ERR_UNKNOWN; -+ } -+} -+ -+oscap_pcre_t *oscap_pcre_compile(const char *pattern, oscap_pcre_options_t options, -+ char **errptr, int *erroffset) -+{ -+ oscap_pcre_t *res = malloc(sizeof(oscap_pcre_t)); -+#ifdef HAVE_PCRE2 -+ int errno; -+ PCRE2_SIZE erroffset2; -+ res->re_ctx = NULL; -+ dD("pcre2_compile_8: patt=%s", pattern); -+ res->re = pcre2_compile_8((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, _oscap_pcre_opts_to_pcre(options), &errno, &erroffset2, NULL); -+ if (res->re == NULL) { -+ PCRE2_UCHAR8 errmsg[PCRE2_ERR_BUF_SIZE]; -+ pcre2_get_error_message_8(errno, errmsg, PCRE2_ERR_BUF_SIZE); -+ dW("pcre2_compile_8: error (at offset %d): %s", erroffset2, errmsg); -+ *erroffset = erroffset2; -+ *errptr = strdup((const char*)errmsg); -+ } -+#else -+ res->re_extra = NULL; -+ dD("pcre_compile: patt=%s", pattern); -+ res->re = pcre_compile(pattern, _oscap_pcre_opts_to_pcre(options), (const char **)errptr, erroffset, NULL); -+ if (res->re == NULL) -+ dW("pcre_compile: error (at offset %d): %s", *erroffset, *errptr); -+#endif -+ if (res->re == NULL) { -+ free(res); -+ res = NULL; -+ } -+ return res; -+} -+ -+void oscap_pcre_optimize(oscap_pcre_t *opcre) -+{ -+#ifdef HAVE_PCRE2 -+ // This is a NOOP for PCRE2 as all patterns are optimized -+ // unless the library configured differently. -+#else -+ const char *errptr = NULL; -+ pcre_extra *extra = pcre_study(opcre->re, 0, &errptr); -+ if (extra != NULL) { -+ if (opcre->re_extra != NULL) -+ free(opcre->re_extra); -+ opcre->re_extra = extra; -+ } -+#endif -+} -+ -+void oscap_pcre_set_match_limit_recursion(oscap_pcre_t *opcre, unsigned long limit) -+{ -+#ifdef HAVE_PCRE2 -+ if (opcre->re_ctx == NULL) { -+ opcre->re_ctx = pcre2_match_context_create_8(NULL); -+ } -+ pcre2_set_depth_limit_8(opcre->re_ctx, limit); -+#else -+ if (opcre->re_extra == NULL) { -+ opcre->re_extra = calloc(1, sizeof(struct pcre_extra)); -+ } -+ opcre->re_extra->match_limit_recursion = limit; -+ opcre->re_extra->flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION; -+#endif -+} -+ -+int oscap_pcre_exec(const oscap_pcre_t *opcre, const char *subject, -+ int length, int startoffset, oscap_pcre_options_t options, -+ int *ovector, int ovecsize) -+{ -+ int rc = 0; -+#ifdef HAVE_PCRE2 -+ // The ovecsize is multiplied by 3 in the code for compatibility with PCRE1 -+ int ovecsize2 = ovecsize/3; -+ pcre2_match_data_8 *mdata = pcre2_match_data_create_8(ovecsize2, NULL); -+ dD("pcre2_match_8: subj=%s", subject); -+ rc = pcre2_match_8(opcre->re, (PCRE2_SPTR8)subject, length, startoffset, _oscap_pcre_opts_to_pcre(options), mdata, opcre->re_ctx); -+ dD("pcre2_match_8: rc=%d, ", rc); -+ if (rc > PCRE2_ERROR_NOMATCH) { -+ PCRE2_SIZE *ovecp = pcre2_get_ovector_pointer_8(mdata); -+ uint32_t ovecp_count = pcre2_get_ovector_count_8(mdata); -+ dD("pcre2_match_8: pcre2_get_ovector_count_8=%d", ovecp_count); -+ for (int i = 0; i < rc; i++) { -+ if (i < ovecsize2) { -+ ovector[i*2] = ovecp[i*2]; -+ ovector[i*2+1] = ovecp[i*2+1]; -+ } -+ } -+ } -+ pcre2_match_data_free_8(mdata); -+#else -+ dD("pcre_exec: subj=%s", subject); -+ rc = pcre_exec(opcre->re, opcre->re_extra, subject, length, startoffset, _oscap_pcre_opts_to_pcre(options), ovector, ovecsize); -+ dD("pcre_exec: rc=%d, ", rc); -+#endif -+ return rc >= 0 ? rc : _pcre_error_to_oscap_pcre(rc); -+} -+ -+void oscap_pcre_free(oscap_pcre_t *opcre) -+{ -+ if (opcre != NULL) { -+#ifdef HAVE_PCRE2 -+ if (opcre->re_ctx != NULL) -+ pcre2_match_context_free_8(opcre->re_ctx); -+ pcre2_code_free_8(opcre->re); -+#else -+ if (opcre->re_extra != NULL) -+ free(opcre->re_extra); -+ pcre_free(opcre->re); -+#endif -+ free(opcre); -+ } -+} -+ -+ -+void oscap_pcre_err_free(char *err) -+{ -+ if (err != NULL) { -+#ifdef HAVE_PCRE2 -+ free(err); -+#else -+ // PCRE1 error messages are static, NOOP. -+#endif -+ } -+} -+ -diff --git a/src/common/oscap_pcre.h b/src/common/oscap_pcre.h -new file mode 100644 -index 00000000000..df8acd01543 ---- /dev/null -+++ b/src/common/oscap_pcre.h -@@ -0,0 +1,106 @@ -+/* -+ * Copyright 2023 Red Hat Inc., Durham, North Carolina. -+ * All Rights Reserved. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ * Authors: -+ * Evgenii Kolesnikov -+ */ -+ -+#ifndef OSCAP_PCRE_ -+#define OSCAP_PCRE_ -+ -+typedef struct oscap_pcre oscap_pcre_t; -+ -+typedef enum { -+ OSCAP_PCRE_OPTS_NONE = 0x0001, -+ OSCAP_PCRE_OPTS_UTF8 = 0x0002, -+ OSCAP_PCRE_OPTS_MULTILINE = 0x0004, -+ OSCAP_PCRE_OPTS_DOTALL = 0x0008, -+ OSCAP_PCRE_OPTS_CASELESS = 0x0010, -+ OSCAP_PCRE_OPTS_NO_UTF8_CHECK = 0x0020, -+ OSCAP_PCRE_OPTS_PARTIAL = 0x0040, -+} oscap_pcre_options_t; -+ -+typedef enum { -+ OSCAP_PCRE_ERR_NOMATCH = -1, -+ OSCAP_PCRE_ERR_PARTIAL = -2, -+ OSCAP_PCRE_ERR_BADPARTIAL = -3, -+ OSCAP_PCRE_ERR_BADUTF8 = -10, -+ OSCAP_PCRE_ERR_RECURSIONLIMIT = -21, -+ OSCAP_PCRE_ERR_UNKNOWN = -100, -+} oscap_pcre_error_t; -+ -+ -+/** -+ * Compile a regular expression string into PCRE object and returns it. -+ * Caller is responsible for freeing the returned object or the error message -+ * if the result is NULL (USE oscap_pcre_err_free()!). -+ * @param pattern expresstion string -+ * @param options compile options -+ * @param errptr a return value for a string representation of error -+ * @param erroffset the offset in the expression where the problem was detected -+ * @return a PCRE object -+ * NULL on failure -+ */ -+oscap_pcre_t* oscap_pcre_compile(const char *pattern, oscap_pcre_options_t options, -+ char **errptr, int *erroffset); -+ -+/** -+ * Execute the compiled regular expression against a string subject and returns -+ * matches count (or a negative error code). -+ * @param opcre the oscap_pcre_t object -+ * @param subject target string -+ * @param length target string length -+ * @param startoffset the offset for the target string -+ * @param options match options -+ * @param ovector the output vector for match offset pairs, see pcre_exec for details -+ * @param ovecsize the size of ovector, see pcre_exec for details -+ * @return matches count -+ * negative error code on failure -+ */ -+int oscap_pcre_exec(const oscap_pcre_t *opcre, const char *subject, -+ int length, int startoffset, oscap_pcre_options_t options, -+ int *ovector, int ovecsize); -+ -+/** -+ * Free the compiled regular expression object. -+ * @param opcre the oscap_pcre_t object -+ */ -+void oscap_pcre_free(oscap_pcre_t *opcre); -+ -+/** -+ * Limit the compiled regular expression object's recursion depth for future -+ * matches. -+ * @param opcre the oscap_pcre_t object -+ * @param limit maximum depth -+ */ -+void oscap_pcre_set_match_limit_recursion(oscap_pcre_t *opcre, unsigned long limit); -+ -+/** -+ * Optimize the compiled regular expression object to increase matching speed. -+ * @param opcre the oscap_pcre_t object -+ */ -+void oscap_pcre_optimize(oscap_pcre_t *opcre); -+ -+ -+/** -+ * Free the error message returned by oscap_pcre_compile. DON'T USE REGULAR free()! -+ * @param err the message -+ */ -+void oscap_pcre_err_free(char *err); -+ -+#endif - -From b34bcbbf559a4f535c936d8e4dcde56da91b1ba0 Mon Sep 17 00:00:00 2001 -From: Evgeny Kolesnikov -Date: Mon, 28 Aug 2023 19:55:52 +0200 -Subject: [PATCH 2/4] Add PCRE2 library #2 - -Use oscap_pcre_* wrapper in the code. ---- - docs/developer/developer.adoc | 8 +- - docs/manual/manual.adoc | 2 +- - src/CPE/cpename.c | 36 ++-- - src/OVAL/oval_component.c | 31 +-- - src/OVAL/oval_schema_version.c | 14 +- - .../probes/independent/system_info_probe.c | 13 +- - .../independent/textfilecontent54_probe.c | 26 +-- - .../independent/textfilecontent_probe.c | 11 +- - .../independent/yamlfilecontent_probe.c | 13 +- - src/OVAL/probes/oval_fts.c | 202 +++--------------- - src/OVAL/probes/oval_fts.h | 5 +- - src/OVAL/probes/unix/gconf_probe.c | 1 - - src/OVAL/probes/unix/linux/partition_probe.c | 13 +- - src/OVAL/probes/unix/linux/rpmverify_probe.c | 11 +- - .../probes/unix/linux/rpmverifyfile_probe.c | 20 +- - .../unix/linux/rpmverifypackage_probe.c | 1 - - src/OVAL/results/oval_cmp_basic.c | 21 +- - src/XCCDF/item.c | 14 +- - src/XCCDF_POLICY/xccdf_policy_remediate.c | 28 +-- - src/common/util.c | 30 ++- - src/common/util.h | 4 +- - .../OVAL/schema_version/test_schema_version.c | 5 + - tests/API/XCCDF/unittests/CMakeLists.txt | 1 + - tests/API/probes/CMakeLists.txt | 1 + - tests/API/probes/oval_fts_list.c | 6 + - .../textfilecontent54/test_recursion_limit.sh | 2 +- - tests/probes/xinetd/CMakeLists.txt | 1 + - 27 files changed, 205 insertions(+), 315 deletions(-) - -diff --git a/docs/developer/developer.adoc b/docs/developer/developer.adoc -index 52502b60ff1..f1a39b3e2b4 100644 ---- a/docs/developer/developer.adoc -+++ b/docs/developer/developer.adoc -@@ -89,6 +89,12 @@ libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-d - libxmlsec1-dev libxmlsec1-openssl - ---- - -+Since version 1.3.9 OpenSCAP can use either PCRE or PCRE2 library to handle regular -+expressions. The default behaviour for 1.3.x line of versions is to try and link -+with PCRE. In order to switxh the build system to PCRE2 one must configure -+CMake with '-DWITH_PCRE2=True' parameter. Dependencies: Debian/Ubuntu — pcre2-dev, -+Fedora/RHEL — pcre2-devel. -+ - When you have all the build dependencies installed you can build the library. - -- - -@@ -319,7 +325,7 @@ behaviour. - * *OSCAP_FULL_VALIDATION=1* - validate all exported documents (slower) - * *SEXP_VALIDATE_DISABLE=1* - do not validate SEXP expressions (faster) - * *OSCAP_PCRE_EXEC_RECURSION_LIMIT* - override default recursion limit -- for match in pcre_exec call in textfilecontent(54) probes. -+ for match in pcre_exec/pcre2_match calls in textfilecontent(54) probes. - - - -diff --git a/docs/manual/manual.adoc b/docs/manual/manual.adoc -index d4ecbdd4335..77f7b32e454 100644 ---- a/docs/manual/manual.adoc -+++ b/docs/manual/manual.adoc -@@ -1613,7 +1613,7 @@ not considered local by the scanner: - * `OSCAP_EVALUATION_TARGET` - Change value of target facts `urn:xccdf:fact:identifier` and `urn:xccdf:fact:asset:identifier:ein` in XCCDF results. Used during offline scanning to pass the name of the target system. - * `OSCAP_FULL_VALIDATION` - If set, XML schema validation will be performed in every step of SCAP content processing. - * `OSCAP_OVAL_COMMAND_OPTIONS` - Additional command line options for `oscap oval` module. The value of this environment variable is appended to the actual command line options of `oscap` command. --* `OSCAP_PCRE_EXEC_RECURSION_LIMIT` - Set recursion limit of regular expression matching using `pcre_exec` function. -+* `OSCAP_PCRE_EXEC_RECURSION_LIMIT` - Set recursion limit of regular expression matching using `pcre_exec`/`pcre2_match` functions. - * `OSCAP_PROBE_ROOT` - Path to a directory which contains mounted filesystem to be evaluated. Used for offline scanning. - * `SEXP_VALIDATE_DISABLE` - If set, `oscap` will not validate SEXP expressions during its execution. - * `SOURCE_DATE_EPOCH` - Timestamp in seconds since epoch. This timestamp will be used instead of the current time to populate `timestamp` attributes in SCAP source data streams created by `oscap ds sds-compose` sub-module. This is used for reproducible builds of data streams. -diff --git a/src/CPE/cpename.c b/src/CPE/cpename.c -index e2e9230f75c..9030149846f 100644 ---- a/src/CPE/cpename.c -+++ b/src/CPE/cpename.c -@@ -37,11 +37,11 @@ - - #include - #include --#include - #include - - #include "cpe_name.h" - #include "common/util.h" -+#include "common/oscap_pcre.h" - #include "oscap_helpers.h" - - #define CPE_URI_SUPPORTED "2.3" -@@ -549,8 +549,8 @@ cpe_format_t cpe_name_get_format_of_str(const char *str) - if (str == NULL) - return CPE_FORMAT_UNKNOWN; - -- pcre *re; -- const char *error; -+ oscap_pcre_t *re; -+ char *error; - int erroffset; - int rc; - int ovector[30]; -@@ -559,26 +559,38 @@ cpe_format_t cpe_name_get_format_of_str(const char *str) - // http://scap.nist.gov/schema/cpe/2.3/cpe-naming_2.3.xsd - // [c] was replaced with [cC] here and in the schemas - -- re = pcre_compile("^[cC][pP][eE]:/[AHOaho]?(:[A-Za-z0-9\\._\\-~%]*){0,6}$", 0, &error, &erroffset, NULL); -- rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovector, 30); -- pcre_free(re); -+ re = oscap_pcre_compile("^[cC][pP][eE]:/[AHOaho]?(:[A-Za-z0-9\\._\\-~%]*){0,6}$", 0, &error, &erroffset); -+ if (re == NULL) { -+ oscap_pcre_err_free(error); -+ return CPE_FORMAT_UNKNOWN; -+ } -+ rc = oscap_pcre_exec(re, str, strlen(str), 0, 0, ovector, 30); -+ oscap_pcre_free(re); - - if (rc >= 0) - return CPE_FORMAT_URI; - - // The regex was taken from the official XSD at - // http://scap.nist.gov/schema/cpe/2.3/cpe-naming_2.3.xsd -- re = pcre_compile("^cpe:2\\.3:[aho\\*\\-](:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){5}(:(([a-zA-Z]{2,3}(-([a-zA-Z]{2}|[0-9]{3}))?)|[\\*\\-]))(:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){4}$", 0, &error, &erroffset, NULL); -- rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovector, 30); -- pcre_free(re); -+ re = oscap_pcre_compile("^cpe:2\\.3:[aho\\*\\-](:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){5}(:(([a-zA-Z]{2,3}(-([a-zA-Z]{2}|[0-9]{3}))?)|[\\*\\-]))(:(((\\?*|\\*?)([a-zA-Z0-9\\-\\._]|(\\\\[\\\\\\*\\?!\"#$$%&'\\(\\)\\+,/:;<=>@\\[\\]\\^`\\{\\|}~]))+(\\?*|\\*?))|[\\*\\-])){4}$", 0, &error, &erroffset); -+ if (re == NULL) { -+ oscap_pcre_err_free(error); -+ return CPE_FORMAT_UNKNOWN; -+ } -+ rc = oscap_pcre_exec(re, str, strlen(str), 0, 0, ovector, 30); -+ oscap_pcre_free(re); - - if (rc >= 0) - return CPE_FORMAT_STRING; - - // FIXME: This should be way more strict -- re = pcre_compile("^wfn:\\[.+\\]$", PCRE_CASELESS, &error, &erroffset, NULL); -- rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovector, 30); -- pcre_free(re); -+ re = oscap_pcre_compile("^wfn:\\[.+\\]$", OSCAP_PCRE_OPTS_CASELESS, &error, &erroffset); -+ if (re == NULL) { -+ oscap_pcre_err_free(error); -+ return CPE_FORMAT_UNKNOWN; -+ } -+ rc = oscap_pcre_exec(re, str, strlen(str), 0, 0, ovector, 30); -+ oscap_pcre_free(re); - - if (rc >= 0) - return CPE_FORMAT_WFN; -diff --git a/src/OVAL/oval_component.c b/src/OVAL/oval_component.c -index 420de1529db..472cf9782a3 100644 ---- a/src/OVAL/oval_component.c -+++ b/src/OVAL/oval_component.c -@@ -55,8 +55,8 @@ - #include "common/debug_priv.h" - #include "common/_error.h" - #include "common/oscap_string.h" -+#include "common/oscap_pcre.h" - #include "oval_glob_to_regex.h" --#include - - #if !defined(OVAL_PROBES_ENABLED) - const char *oval_subtype_to_str(oval_subtype_t subtype); -@@ -1980,12 +1980,16 @@ static long unsigned int _parse_fmt_sse(char *dt) - static bool _match(const char *pattern, const char *string) - { - bool match = false; -- pcre *re; -- const char *error; -+ oscap_pcre_t *re; -+ char *error; - int erroffset = -1, ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]); -- re = pcre_compile(pattern, PCRE_UTF8, &error, &erroffset, NULL); -- match = (pcre_exec(re, NULL, string, strlen(string), 0, 0, ovector, ovector_len) >= 0); -- pcre_free(re); -+ re = oscap_pcre_compile(pattern, OSCAP_PCRE_OPTS_UTF8, &error, &erroffset); -+ if (re == NULL) { -+ oscap_pcre_err_free(error); -+ return false; -+ } -+ match = (oscap_pcre_exec(re, string, strlen(string), 0, 0, ovector, ovector_len) >= 0); -+ oscap_pcre_free(re); - return match; - } - -@@ -2208,13 +2212,14 @@ static oval_syschar_collection_flag_t _oval_component_evaluate_REGEX_CAPTURE(ova - int rc; - char *pattern; - int erroffset = -1; -- pcre *re = NULL; -- const char *error; -+ oscap_pcre_t *re = NULL; -+ char *error; - - pattern = oval_component_get_regex_pattern(component); -- re = pcre_compile(pattern, PCRE_UTF8, &error, &erroffset, NULL); -+ re = oscap_pcre_compile(pattern, OSCAP_PCRE_OPTS_UTF8, &error, &erroffset); - if (re == NULL) { -- dE("pcre_compile() failed: \"%s\".", error); -+ dE("oscap_pcre_compile() failed: \"%s\".", error); -+ oscap_pcre_err_free(error); - return SYSCHAR_FLAG_ERROR; - } - -@@ -2233,9 +2238,9 @@ static oval_syschar_collection_flag_t _oval_component_evaluate_REGEX_CAPTURE(ova - for (i = 0; i < ovector_len; ++i) - ovector[i] = -1; - -- rc = pcre_exec(re, NULL, text, strlen(text), 0, 0, ovector, ovector_len); -+ rc = oscap_pcre_exec(re, text, strlen(text), 0, 0, ovector, ovector_len); - if (rc < -1) { -- dE("pcre_exec() failed: %d.", rc); -+ dE("oscap_pcre_exec() failed: %d.", rc); - flag = SYSCHAR_FLAG_ERROR; - break; - } -@@ -2263,7 +2268,7 @@ static oval_syschar_collection_flag_t _oval_component_evaluate_REGEX_CAPTURE(ova - oval_collection_free_items(subcoll, (oscap_destruct_func) oval_value_free); - } - oval_component_iterator_free(subcomps); -- pcre_free(re); -+ oscap_pcre_free(re); - return flag; - } - -diff --git a/src/OVAL/oval_schema_version.c b/src/OVAL/oval_schema_version.c -index 9f2d332d5a6..9828f3d6328 100644 ---- a/src/OVAL/oval_schema_version.c -+++ b/src/OVAL/oval_schema_version.c -@@ -29,12 +29,11 @@ - #include - #include - #include "common/util.h" -+#include "common/oscap_pcre.h" - #include "common/debug_priv.h" - #include "public/oval_schema_version.h" - --#include -- --#define OVECTOR_LEN 30 // must be a multiple of 30 -+#define OVECTOR_LEN 60 // must be a multiple of 30 - - static int _parse_int(const char *substring, size_t substring_length) - { -@@ -55,16 +54,17 @@ oval_schema_version_t oval_schema_version_from_cstr(const char *ver_str) - return version; - } - const char *pattern = "([0-9]+)\\.([0-9]+)(?:\\.([0-9]+))?(?::([0-9]+)\\.([0-9]+)(?:\\.([0-9]+))?)?"; -- const char *error; -+ char *error; - int erroffset; -- pcre *re = pcre_compile(pattern, 0, &error, &erroffset, NULL); -+ oscap_pcre_t *re = oscap_pcre_compile(pattern, 0, &error, &erroffset); - if (re == NULL) { - dE("Regular expression compilation failed with %s", pattern); -+ oscap_pcre_err_free(error); - return version; - } - int ovector[OVECTOR_LEN]; -- int rc = pcre_exec(re, NULL, ver_str, strlen(ver_str), 0, 0, ovector, OVECTOR_LEN); -- pcre_free(re); -+ int rc = oscap_pcre_exec(re, ver_str, strlen(ver_str), 0, 0, ovector, OVECTOR_LEN); -+ oscap_pcre_free(re); - if (rc < 0) { - dE("Regular expression %s did not match string %s", pattern, ver_str); - return version; -diff --git a/src/OVAL/probes/independent/system_info_probe.c b/src/OVAL/probes/independent/system_info_probe.c -index 9f680e14d27..6a239565f80 100644 ---- a/src/OVAL/probes/independent/system_info_probe.c -+++ b/src/OVAL/probes/independent/system_info_probe.c -@@ -101,7 +101,6 @@ - #include - #include - #include --#include - #elif defined(OS_FREEBSD) - #include - #include -@@ -540,21 +539,23 @@ static char *_get_os_release_elem(char *os_release_data, const char *elem_name) - char elem_re[128] = {0}; - snprintf(elem_re, sizeof(elem_re), "%s%s%s", "^", elem_name, "=[\"']?(.*?)[\"']?$"); - -- const char *error; -+ char *error; - int erroffset, ovec[_REGEX_RES_VECSIZE] = {0}; -- pcre *re = pcre_compile(elem_re, PCRE_MULTILINE, &error, &erroffset, NULL); -- if (re == NULL) -+ oscap_pcre_t *re = oscap_pcre_compile(elem_re, OSCAP_PCRE_OPTS_MULTILINE, &error, &erroffset); -+ if (re == NULL) { -+ oscap_pcre_err_free(error); - goto finish; -+ } - - char *ptr = NULL; -- int rc = pcre_exec(re, NULL, os_release_data, len, 0, 0, ovec, _REGEX_RES_VECSIZE); -+ int rc = oscap_pcre_exec(re, os_release_data, len, 0, 0, ovec, _REGEX_RES_VECSIZE); - if (rc >= 0) { - /* ovec[0] and ovec[1] - are the start and the end of the whole pattern match (=".....") - * ovec[2] and ovec[3] - are start and end char positions of the capture group (.*?) */ - ptr = strndup(os_release_data+ovec[2], ovec[3]-ovec[2]); - ret = ptr; - } -- pcre_free(re); -+ oscap_pcre_free(re); - - finish: - return ret; -diff --git a/src/OVAL/probes/independent/textfilecontent54_probe.c b/src/OVAL/probes/independent/textfilecontent54_probe.c -index 322977418ca..af60cdf20a5 100644 ---- a/src/OVAL/probes/independent/textfilecontent54_probe.c -+++ b/src/OVAL/probes/independent/textfilecontent54_probe.c -@@ -43,7 +43,6 @@ - #include - #include - #include --#include - - #include "_seap.h" - #include -@@ -53,6 +52,7 @@ - #include - #include "common/debug_priv.h" - #include "common/util.h" -+#include "common/oscap_pcre.h" - #include "textfilecontent54_probe.h" - - #define FILE_SEPARATOR '/' -@@ -112,10 +112,10 @@ static SEXP_t *create_item(const char *path, const char *filename, char *pattern - - struct pfdata { - char *pattern; -- int re_opts; -+ oscap_pcre_options_t re_opts; - SEXP_t *instance_ent; -- probe_ctx *ctx; -- pcre *compiled_regex; -+ probe_ctx *ctx; -+ oscap_pcre_t *compiled_regex; - }; - - static int process_file(const char *prefix, const char *path, const char *file, void *arg, oval_schema_version_t over) -@@ -274,7 +274,7 @@ int textfilecontent54_probe_main(probe_ctx *ctx, void *arg) - struct pfdata pfd; - int ret = 0; - int errorffset = -1; -- const char *error; -+ char *error; - OVAL_FTS *ofts; - OVAL_FTSENT *ofts_ent; - -@@ -316,38 +316,38 @@ int textfilecontent54_probe_main(probe_ctx *ctx, void *arg) - - pfd.instance_ent = inst_ent; - pfd.ctx = ctx; -- pfd.re_opts = PCRE_UTF8; -+ pfd.re_opts = OSCAP_PCRE_OPTS_UTF8; - r0 = probe_ent_getattrval(bh_ent, "ignore_case"); - if (r0) { - val = SEXP_string_getb(r0); - SEXP_free(r0); - if (val) -- pfd.re_opts |= PCRE_CASELESS; -+ pfd.re_opts |= OSCAP_PCRE_OPTS_CASELESS; - } - r0 = probe_ent_getattrval(bh_ent, "multiline"); - if (r0) { - val = SEXP_string_getb(r0); - SEXP_free(r0); - if (val) -- pfd.re_opts |= PCRE_MULTILINE; -+ pfd.re_opts |= OSCAP_PCRE_OPTS_MULTILINE; - } - r0 = probe_ent_getattrval(bh_ent, "singleline"); - if (r0) { - val = SEXP_string_getb(r0); - SEXP_free(r0); - if (val) -- pfd.re_opts |= PCRE_DOTALL; -+ pfd.re_opts |= OSCAP_PCRE_OPTS_DOTALL; - } - -- pfd.compiled_regex = pcre_compile(pfd.pattern, pfd.re_opts, &error, -- &errorffset, NULL); -+ pfd.compiled_regex = oscap_pcre_compile(pfd.pattern, pfd.re_opts, &error, &errorffset); - if (pfd.compiled_regex == NULL) { - SEXP_t *msg; - -- msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "pcre_compile() '%s' %s.", pfd.pattern, error); -+ msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "oscap_pcre_compile() '%s' %s.", pfd.pattern, error); - probe_cobj_add_msg(probe_ctx_getresult(pfd.ctx), msg); - SEXP_free(msg); - probe_cobj_set_flag(probe_ctx_getresult(pfd.ctx), SYSCHAR_FLAG_ERROR); -+ oscap_pcre_err_free(error); - goto cleanup; - } - -@@ -375,6 +375,6 @@ int textfilecontent54_probe_main(probe_ctx *ctx, void *arg) - if (pfd.pattern != NULL) - free(pfd.pattern); - if (pfd.compiled_regex != NULL) -- pcre_free(pfd.compiled_regex); -+ oscap_pcre_free(pfd.compiled_regex); - return ret; - } -diff --git a/src/OVAL/probes/independent/textfilecontent_probe.c b/src/OVAL/probes/independent/textfilecontent_probe.c -index 988a6471dcf..224f0ea21a3 100644 ---- a/src/OVAL/probes/independent/textfilecontent_probe.c -+++ b/src/OVAL/probes/independent/textfilecontent_probe.c -@@ -62,7 +62,6 @@ - #include - #include - #include --#include - - #include "_seap.h" - #include -@@ -72,6 +71,7 @@ - #include - #include "common/debug_priv.h" - #include "common/util.h" -+#include "common/oscap_pcre.h" - #include "textfilecontent_probe.h" - - #define FILE_SEPARATOR '/' -@@ -148,11 +148,12 @@ static int process_file(const char *prefix, const char *path, const char *filena - - // todo: move to probe_main()? - int erroffset = -1; -- pcre *re = NULL; -- const char *error; -+ oscap_pcre_t *re = NULL; -+ char *error; - -- re = pcre_compile(pfd->pattern, PCRE_UTF8, &error, &erroffset, NULL); -+ re = oscap_pcre_compile(pfd->pattern, OSCAP_PCRE_OPTS_UTF8, &error, &erroffset); - if (re == NULL) { -+ oscap_pcre_err_free(error); - return -1; - } - -@@ -218,7 +219,7 @@ static int process_file(const char *prefix, const char *path, const char *filena - if (whole_path != NULL) - free(whole_path); - if (re != NULL) -- pcre_free(re); -+ oscap_pcre_free(re); - free(whole_path_with_prefix); - - return ret; -diff --git a/src/OVAL/probes/independent/yamlfilecontent_probe.c b/src/OVAL/probes/independent/yamlfilecontent_probe.c -index 2d0cac69913..f4698ff4d53 100644 ---- a/src/OVAL/probes/independent/yamlfilecontent_probe.c -+++ b/src/OVAL/probes/independent/yamlfilecontent_probe.c -@@ -26,7 +26,6 @@ - - #include - #include --#include - #include - #include - -@@ -36,6 +35,7 @@ - #include "oval_fts.h" - #include "list.h" - #include "probe/probe.h" -+#include "common/oscap_pcre.h" - - #define OSCAP_YAML_STRING_TAG "tag:yaml.org,2002:str" - #define OSCAP_YAML_BOOL_TAG "tag:yaml.org,2002:bool" -@@ -52,17 +52,18 @@ int yamlfilecontent_probe_offline_mode_supported() - - static bool match_regex(const char *pattern, const char *value) - { -- const char *errptr; -+ char *errptr; - int erroroffset; -- pcre *re = pcre_compile(pattern, 0, &errptr, &erroroffset, NULL); -+ oscap_pcre_t *re = oscap_pcre_compile(pattern, 0, &errptr, &erroroffset); - if (re == NULL) { -- dE("pcre_compile failed on pattern '%s': %s at %d", pattern, -+ dE("oscap_pcre_compile failed on pattern '%s': %s at %d", pattern, - errptr, erroroffset); -+ oscap_pcre_err_free(errptr); - return false; - } - int ovector[OVECCOUNT]; -- int rc = pcre_exec(re, NULL, value, strlen(value), 0, 0, ovector, OVECCOUNT); -- pcre_free(re); -+ int rc = oscap_pcre_exec(re, value, strlen(value), 0, 0, ovector, OVECCOUNT); -+ oscap_pcre_free(re); - if (rc > 0) { - return true; - } -diff --git a/src/OVAL/probes/oval_fts.c b/src/OVAL/probes/oval_fts.c -index c96247b0945..e4106720208 100644 ---- a/src/OVAL/probes/oval_fts.c -+++ b/src/OVAL/probes/oval_fts.c -@@ -32,7 +32,6 @@ - #include - #include - #include --#include - - #include "oscap_helpers.h" - #include "fsdev.h" -@@ -379,150 +378,20 @@ static char *extract_fixed_path_prefix(char *path) - return strdup("/"); - } - --static int badpartial_check_slash(const char *pattern) --{ -- pcre *regex; -- const char *errptr = NULL; -- int errofs = 0, fb, ret; -- -- regex = pcre_compile(pattern + 1 /* skip '^' */, 0, &errptr, &errofs, NULL); -- if (regex == NULL) { -- dE("Failed to validate the pattern: pcre_compile(): " -- "error: '%s', error offset: %d, pattern: '%s'.\n", -- errptr, errofs, pattern); -- return -1; -- } -- ret = pcre_fullinfo(regex, NULL, PCRE_INFO_FIRSTBYTE, &fb); -- pcre_free(regex); -- regex = NULL; -- if (ret != 0) { -- dE("Failed to validate the pattern: pcre_fullinfo(): " -- "return code: %d, pattern: '%s'.\n", ret, pattern); -- return -1; -- } -- if (fb != '/') { -- dE("Failed to validate the pattern: pcre_fullinfo(): " -- "first byte: %d '%c', pattern: '%s' - the first " -- "byte should be a '/'.\n", fb, fb, pattern); -- return -2; -- } -- -- return 0; --} -- - #define TEST_PATH1 "/" - #define TEST_PATH2 "x" - --static int badpartial_transform_pattern(char *pattern, pcre **regex_out) --{ -- /* -- PCREPARTIAL(3) -- http://pcre.org/pcre.txt -- Last updated: 21 January 2012 -- -- For releases of PCRE prior to 8.00, because of the way -- certain internal optimizations were implemented in the -- pcre_exec() function, the PCRE_PARTIAL option (predecessor -- of PCRE_PARTIAL_SOFT) could not be used with all patterns. -- -- Items that were formerly restricted were repeated single -- characters and repeated metasequences. If PCRE_PARTIAL was -- set for a pattern that did not conform to the restrictions, -- pcre_exec() returned the error code PCRE_ERROR_BADPARTIAL -- (-13). -- */ -- -- int ret, brkt_lvl = 0, errofs = 0; -- const char *rchars = "\\[]()*+{"; /* probably incomplete */ -- const char *test_path1 = TEST_PATH1; -- const char *errptr = NULL; -- char *s, *brkt_mark; -- bool bracketed = false, found_regex = false; -- pcre *regex; -- -- /* The processing bellow builds upon the assumption that -- the pattern has been validated by pcre_compile() */ -- for (s = brkt_mark = pattern; (s = strpbrk(s, rchars)) != NULL; s++) { -- switch (*s) { -- case '\\': -- s++; -- break; -- case '[': -- if (!bracketed) { -- bracketed = true; -- if (s[1] == ']') -- s++; -- } -- break; -- case ']': -- bracketed = false; -- break; -- case '(': -- if (!bracketed) { -- if (brkt_lvl++ == 0) -- brkt_mark = s; -- } -- break; -- case ')': -- if (!bracketed) -- brkt_lvl--; -- break; -- default: -- if (!bracketed) -- found_regex = true; -- break; -- } -- if (found_regex) -- break; -- } -- -- if (s == NULL) { -- dW("Nonfatal failure: can't transform the pattern for partial " -- "match optimization: none of the suspected culprits found, " -- "pattern: '%s'.", pattern); -- return -1; -- } -- -- if (brkt_lvl > 0) -- *brkt_mark = '\0'; -- else -- *s = '\0'; -- -- regex = pcre_compile(pattern, 0, &errptr, &errofs, NULL); -- if (regex == NULL) { -- dW("Nonfatal failure: can't transform the pattern for partial " -- "match optimization, error: '%s', error offset: %d, " -- "pattern: '%s'.", errptr, errofs, pattern); -- return -1; -- } -- -- ret = pcre_exec(regex, NULL, test_path1, strlen(test_path1), 0, -- PCRE_PARTIAL, NULL, 0); -- if (ret != PCRE_ERROR_PARTIAL && ret < 0) { -- pcre_free(regex); -- dW("Nonfatal failure: can't transform the pattern for partial " -- "match optimization, pcre_exec() return code: %d, pattern: " -- "'%s'.", ret, pattern); -- return -1; -- } -- -- if (regex_out != NULL) -- *regex_out = regex; -- -- return 0; --} -- - /* Verify that the path is usable and try to craft a regex to speed up - the filesystem traversal. If the path to match is ill-designed, an - ugly heuristic is employed to obtain something meaningfull. */ --static int process_pattern_match(const char *path, pcre **regex_out) -+static int process_pattern_match(const char *path, oscap_pcre_t **regex_out) - { - int ret, errofs = 0; - char *pattern; - const char *test_path1 = TEST_PATH1; - //const char *test_path2 = TEST_PATH2; -- const char *errptr = NULL; -- pcre *regex; -+ char *errptr = NULL; -+ oscap_pcre_t *regex; - - if (path[0] != '^') { - /* Matching has to have a fixed starting point and thus -@@ -540,19 +409,20 @@ static int process_pattern_match(const char *path, pcre **regex_out) - pattern = strdup(path); - } - -- regex = pcre_compile(pattern, 0, &errptr, &errofs, NULL); -+ regex = oscap_pcre_compile(pattern, 0, &errptr, &errofs); - if (regex == NULL) { -- dE("Failed to validate the pattern: pcre_compile(): " -+ dE("Failed to validate the pattern: oscap_pcre_compile(): " - "error offset: %d, error: '%s', pattern: '%s'.\n", - errofs, errptr, pattern); - free(pattern); -+ oscap_pcre_err_free(errptr); - return -1; - } -- ret = pcre_exec(regex, NULL, test_path1, strlen(test_path1), 0, -- PCRE_PARTIAL, NULL, 0); -+ ret = oscap_pcre_exec(regex, test_path1, strlen(test_path1), 0, -+ OSCAP_PCRE_OPTS_PARTIAL, NULL, 0); - - switch (ret) { -- case PCRE_ERROR_PARTIAL: -+ case OSCAP_PCRE_ERR_PARTIAL: - /* The pattern has matched a prefix of the test path - and probably begins with a slash. Make sure that it - doesn't match an arbitrary prefix. */ -@@ -577,35 +447,15 @@ static int process_pattern_match(const char *path, pcre **regex_out) - } - */ - break; -- case PCRE_ERROR_BADPARTIAL: -- dD("pcre_exec() returned PCRE_ERROR_BADPARTIAL for pattern " -- "'%s' and a test path '%s'. Falling back to " -- "pcre_fullinfo().\n", pattern, test_path1); -- pcre_free(regex); -- regex = NULL; -- -- /* Fallback to first byte check to determin if -- the pattern begins with a slash. */ -- ret = badpartial_check_slash((const char *) pattern); -- if (ret != 0) { -- free(pattern); -- return ret; -- } -- /* The pattern contains features that this version of -- PCRE can't handle for partial matching. At least -- try to find the longest well-bracketed prefix that -- can be handled. */ -- badpartial_transform_pattern(pattern, ®ex); -- break; -- case PCRE_ERROR_NOMATCH: -+ case OSCAP_PCRE_ERR_NOMATCH: - /* The pattern doesn't contain a leading slash (or - some part of this code is broken). Apologise to the - user and fail. */ -- dE("Failed to validate the pattern: pcre_exec() returned " -+ dE("Failed to validate the pattern: oscap_pcre_exec() returned " - "PCRE_ERROR_NOMATCH for pattern '%s' and a test path '%s'. " - "This indicates the pattern doesn't match a leading '/'.\n", - pattern, test_path1); -- pcre_free(regex); -+ oscap_pcre_free(regex); - free(pattern); - return -2; - default: -@@ -634,10 +484,10 @@ static int process_pattern_match(const char *path, pcre **regex_out) - break; - } - /* Some other error. */ -- dE("Failed to validate the pattern: pcre_exec() return " -+ dE("Failed to validate the pattern: oscap_pcre_exec() return " - "code: %d, pattern '%s', test path '%s'.\n", ret, - pattern, test_path1); -- pcre_free(regex); -+ oscap_pcre_free(regex); - free(pattern); - return -1; - } -@@ -685,7 +535,7 @@ OVAL_FTS *oval_fts_open_prefixed(const char *prefix, SEXP_t *path, SEXP_t *filen - - uint32_t path_op; - bool nilfilename = false; -- pcre *regex = NULL; -+ oscap_pcre_t *regex = NULL; - struct stat st; - - if ((path != NULL || filename != NULL || filepath == NULL) -@@ -845,7 +695,7 @@ OVAL_FTS *oval_fts_open_prefixed(const char *prefix, SEXP_t *path, SEXP_t *filen - errno, strerror(errno)); - } - free((void *) paths[0]); -- pcre_free(regex); -+ oscap_pcre_free(regex); - return NULL; - } - -@@ -861,17 +711,15 @@ OVAL_FTS *oval_fts_open_prefixed(const char *prefix, SEXP_t *path, SEXP_t *filen - if (ofts->ofts_match_path_fts == NULL || errno != 0) { - dE("fts_open() failed, errno: %d \"%s\".", errno, strerror(errno)); - OVAL_FTS_free(ofts); -- pcre_free(regex); -+ oscap_pcre_free(regex); - return (NULL); - } - - ofts->ofts_recurse_path_fts_opts = rec_fts_options; - ofts->ofts_path_op = path_op; - if (regex != NULL) { -- const char *errptr = NULL; -- - ofts->ofts_path_regex = regex; -- ofts->ofts_path_regex_extra = pcre_study(regex, 0, &errptr); -+ oscap_pcre_optimize(regex); - } - - if (filesystem == OVAL_RECURSE_FS_LOCAL) { -@@ -997,20 +845,20 @@ static FTSENT *oval_fts_read_match_path(OVAL_FTS *ofts) - if (ofts->ofts_path_regex != NULL && fts_ent->fts_info == FTS_D) { - int ret, svec[3]; - -- ret = pcre_exec(ofts->ofts_path_regex, ofts->ofts_path_regex_extra, -- fts_ent->fts_path+shift, fts_ent->fts_pathlen-shift, 0, PCRE_PARTIAL, -+ ret = oscap_pcre_exec(ofts->ofts_path_regex, -+ fts_ent->fts_path+shift, fts_ent->fts_pathlen-shift, 0, OSCAP_PCRE_OPTS_PARTIAL, - svec, sizeof(svec) / sizeof(svec[0])); - if (ret < 0) { - switch (ret) { -- case PCRE_ERROR_NOMATCH: -+ case OSCAP_PCRE_ERR_NOMATCH: - dD("Partial match optimization: PCRE_ERROR_NOMATCH, skipping."); - fts_set(ofts->ofts_match_path_fts, fts_ent, FTS_SKIP); - continue; -- case PCRE_ERROR_PARTIAL: -+ case OSCAP_PCRE_ERR_PARTIAL: - dD("Partial match optimization: PCRE_ERROR_PARTIAL, continuing."); - continue; - default: -- dE("pcre_exec() error: %d.", ret); -+ dE("oscap_pcre_exec() error: %d.", ret); - return NULL; - } - } -@@ -1384,9 +1232,7 @@ int oval_fts_close(OVAL_FTS *ofts) - free(ofts->ofts_recurse_path_pthcpy); - - if (ofts->ofts_path_regex) -- pcre_free(ofts->ofts_path_regex); -- if (ofts->ofts_path_regex_extra) -- pcre_free(ofts->ofts_path_regex_extra); -+ oscap_pcre_free(ofts->ofts_path_regex); - - if (ofts->ofts_spath != NULL) - SEXP_free(ofts->ofts_spath); -diff --git a/src/OVAL/probes/oval_fts.h b/src/OVAL/probes/oval_fts.h -index d4d898fea64..0134654f4e4 100644 ---- a/src/OVAL/probes/oval_fts.h -+++ b/src/OVAL/probes/oval_fts.h -@@ -30,8 +30,8 @@ - #else - #include - #endif --#include - #include "fsdev.h" -+#include "common/oscap_pcre.h" - - #define ENT_GET_AREF(ent, dst, attr_name, mandatory) \ - do { \ -@@ -78,8 +78,7 @@ typedef struct { - char *ofts_recurse_path_curpth; - dev_t ofts_recurse_path_devid; - -- pcre *ofts_path_regex; -- pcre_extra *ofts_path_regex_extra; -+ oscap_pcre_t *ofts_path_regex; - uint32_t ofts_path_op; - - SEXP_t *ofts_spath; -diff --git a/src/OVAL/probes/unix/gconf_probe.c b/src/OVAL/probes/unix/gconf_probe.c -index e41d6741401..3ddfb628218 100644 ---- a/src/OVAL/probes/unix/gconf_probe.c -+++ b/src/OVAL/probes/unix/gconf_probe.c -@@ -36,7 +36,6 @@ - #include - #include - #include --#include - #include - #include "gconf_probe.h" - -diff --git a/src/OVAL/probes/unix/linux/partition_probe.c b/src/OVAL/probes/unix/linux/partition_probe.c -index be51f2de850..cd0e1041327 100644 ---- a/src/OVAL/probes/unix/linux/partition_probe.c -+++ b/src/OVAL/probes/unix/linux/partition_probe.c -@@ -63,9 +63,9 @@ - #include - #include - #include --#include - - #include "common/debug_priv.h" -+#include "common/oscap_pcre.h" - #include "partition_probe.h" - - #ifndef MTAB_PATH -@@ -346,8 +346,8 @@ int partition_probe_main(probe_ctx *ctx, void *probe_arg) - char buffer[MTAB_LINE_MAX]; - struct mntent mnt_ent, *mnt_entp; - -- pcre *re = NULL; -- const char *estr = NULL; -+ oscap_pcre_t *re = NULL; -+ char *estr = NULL; - int eoff = -1; - #if defined(HAVE_BLKID_GET_TAG_VALUE) - blkid_cache blkcache; -@@ -358,13 +358,14 @@ int partition_probe_main(probe_ctx *ctx, void *probe_arg) - } - #endif - if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) { -- re = pcre_compile(mnt_path, PCRE_UTF8, &estr, &eoff, NULL); -+ re = oscap_pcre_compile(mnt_path, OSCAP_PCRE_OPTS_UTF8, &estr, &eoff); - - if (re == NULL) { - endmntent(mnt_fp); - #if defined(HAVE_BLKID_GET_TAG_VALUE) - blkid_put_cache(blkcache); - #endif -+ oscap_pcre_err_free(estr); - return (PROBE_EINVAL); - } - } -@@ -398,7 +399,7 @@ int partition_probe_main(probe_ctx *ctx, void *probe_arg) - } else if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) { - int rc; - -- rc = pcre_exec(re, NULL, mnt_entp->mnt_dir, -+ rc = oscap_pcre_exec(re, mnt_entp->mnt_dir, - strlen(mnt_entp->mnt_dir), 0, 0, NULL, 0); - - if (rc == 0) { -@@ -418,7 +419,7 @@ int partition_probe_main(probe_ctx *ctx, void *probe_arg) - endmntent(mnt_fp); - - if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) -- pcre_free(re); -+ oscap_pcre_free(re); - #if defined(HAVE_BLKID_GET_TAG_VALUE) - blkid_put_cache(blkcache); - #endif -diff --git a/src/OVAL/probes/unix/linux/rpmverify_probe.c b/src/OVAL/probes/unix/linux/rpmverify_probe.c -index 14ee57d89a5..6a8f4b4992e 100644 ---- a/src/OVAL/probes/unix/linux/rpmverify_probe.c -+++ b/src/OVAL/probes/unix/linux/rpmverify_probe.c -@@ -39,7 +39,6 @@ - #include - #include - #include --#include - - #include "rpm-helper.h" - -@@ -54,6 +53,7 @@ - - #include - #include -+#include "common/oscap_pcre.h" - - #include "rpmverify_probe.h" - -@@ -83,18 +83,19 @@ static int rpmverify_collect(probe_ctx *ctx, - rpmdbMatchIterator match; - rpmVerifyAttrs omit = (rpmVerifyAttrs)(flags & RPMVERIFY_RPMATTRMASK); - Header pkgh; -- pcre *re = NULL; -+ oscap_pcre_t *re = NULL; - int ret = -1; - - /* pre-compile regex if needed */ - if (file_op == OVAL_OPERATION_PATTERN_MATCH) { -- const char *errmsg; -+ char *errmsg; - int erroff; - -- re = pcre_compile(file, PCRE_UTF8, &errmsg, &erroff, NULL); -+ re = oscap_pcre_compile(file, OSCAP_PCRE_OPTS_UTF8, &errmsg, &erroff); - - if (re == NULL) { - /* TODO */ -+ oscap_pcre_err_free(errmsg); - return (-1); - } - } -@@ -213,7 +214,7 @@ static int rpmverify_collect(probe_ctx *ctx, - ret = 0; - ret: - if (re != NULL) -- pcre_free(re); -+ oscap_pcre_free(re); - - RPMVERIFY_UNLOCK; - return (ret); -diff --git a/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c b/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c -index a61f44e39b7..12145c411f4 100644 ---- a/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c -+++ b/src/OVAL/probes/unix/linux/rpmverifyfile_probe.c -@@ -41,7 +41,6 @@ - #include - #include - #include --#include - - #include "rpm-helper.h" - #include "oscap_helpers.h" -@@ -57,6 +56,8 @@ - - #include - #include -+#include "common/oscap_pcre.h" -+ - #include "rpmverifyfile_probe.h" - - struct rpmverify_res { -@@ -154,25 +155,26 @@ static int _compare_file_with_current_file(oval_operation_t file_op, const char - } - *result_file = current_file_realpath ? oscap_strdup(current_file_realpath) : oscap_strdup(current_file); - } else if (file_op == OVAL_OPERATION_PATTERN_MATCH) { -- const char *errmsg; -+ char *errmsg; - int erroff; -- pcre *re = pcre_compile(file, PCRE_UTF8, &errmsg, &erroff, NULL); -+ oscap_pcre_t *re = oscap_pcre_compile(file, OSCAP_PCRE_OPTS_UTF8, &errmsg, &erroff); - if (re == NULL) { -- dE("pcre_compile pattern='%s': %s", file, errmsg); -+ dE("oscap_pcre_compile pattern='%s': %s", file, errmsg); - ret = -1; -+ oscap_pcre_err_free(errmsg); - goto cleanup; - } -- int pcre_ret = pcre_exec(re, NULL, current_file, strlen(current_file), 0, 0, NULL, 0); -- pcre_free(re); -- if (pcre_ret == 0) { -+ int pcre_ret = oscap_pcre_exec(re, current_file, strlen(current_file), 0, 0, NULL, 0); -+ oscap_pcre_free(re); -+ if (pcre_ret > OSCAP_PCRE_ERR_NOMATCH) { - /* match */ - *result_file = oscap_strdup(current_file); -- } else if (pcre_ret == -1) { -+ } else if (pcre_ret == OSCAP_PCRE_ERR_NOMATCH) { - /* no match */ - ret = 1; - goto cleanup; - } else { -- dE("pcre_exec() failed!"); -+ dE("oscap_pcre_exec() failed!"); - ret = -1; - goto cleanup; - } -diff --git a/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c b/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c -index b56fd43d11e..87a91240757 100644 ---- a/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c -+++ b/src/OVAL/probes/unix/linux/rpmverifypackage_probe.c -@@ -41,7 +41,6 @@ - #include - #include - #include --#include - - #include "rpm-helper.h" - #include "probe-chroot.h" -diff --git a/src/OVAL/results/oval_cmp_basic.c b/src/OVAL/results/oval_cmp_basic.c -index 7b819d5538d..48fbcf121fc 100644 ---- a/src/OVAL/results/oval_cmp_basic.c -+++ b/src/OVAL/results/oval_cmp_basic.c -@@ -27,10 +27,10 @@ - - #include - #include --#include - - #include "oval_types.h" - #include "common/_error.h" -+#include "common/oscap_pcre.h" - #include "common/debug_priv.h" - #include "oval_cmp_basic_impl.h" - -@@ -124,29 +124,30 @@ static oval_result_t strregcomp(const char *pattern, const char *test_str) - { - int ret; - oval_result_t result = OVAL_RESULT_ERROR; -- pcre *re; -- const char *err; -+ oscap_pcre_t *re; -+ char *err; - int errofs; - -- re = pcre_compile(pattern, PCRE_UTF8, &err, &errofs, NULL); -+ re = oscap_pcre_compile(pattern, OSCAP_PCRE_OPTS_UTF8, &err, &errofs); - if (re == NULL) { - dE("Unable to compile regex pattern '%s', " -- "pcre_compile() returned error (offset: %d): '%s'.\n", pattern, errofs, err); -+ "oscap_pcre_compile() returned error (offset: %d): '%s'.\n", pattern, errofs, err); -+ oscap_pcre_err_free(err); - return OVAL_RESULT_ERROR; - } - -- ret = pcre_exec(re, NULL, test_str, strlen(test_str), 0, 0, NULL, 0); -- if (ret > -1 ) { -+ ret = oscap_pcre_exec(re, test_str, strlen(test_str), 0, 0, NULL, 0); -+ if (ret > OSCAP_PCRE_ERR_NOMATCH ) { - result = OVAL_RESULT_TRUE; -- } else if (ret == -1) { -+ } else if (ret == OSCAP_PCRE_ERR_NOMATCH) { - result = OVAL_RESULT_FALSE; - } else { - dE("Unable to match regex pattern '%s' on string '%s', " -- "pcre_exec() returned error: %d.\n", pattern, test_str, ret); -+ "oscap_pcre_exec() returned error: %d.\n", pattern, test_str, ret); - result = OVAL_RESULT_ERROR; - } - -- pcre_free(re); -+ oscap_pcre_free(re); - return result; - } - -diff --git a/src/XCCDF/item.c b/src/XCCDF/item.c -index 295e4a7f00a..042d9b3d769 100644 ---- a/src/XCCDF/item.c -+++ b/src/XCCDF/item.c -@@ -30,7 +30,6 @@ - #include - #include - #include --#include - - #include - #include -@@ -41,6 +40,7 @@ - #include "helpers.h" - #include "xccdf_impl.h" - #include "common/util.h" -+#include "common/oscap_pcre.h" - #include "oscap_helpers.h" - - /* According to `man 3 pcreapi`, the number passed in ovecsize should always -@@ -768,12 +768,16 @@ void xccdf_item_add_applicable_platform(struct xccdf_item *item, xmlTextReaderPt - * an underscore to workaround the situation that this XCCDF benchmark is - * not applicable. - */ -- const char *pcreerror = NULL; -+ char *pcreerror = NULL; - int erroffset = 0; -- pcre *regex = pcre_compile("^(cpe:/o:microsoft:windows)(7.*)", 0, &pcreerror, &erroffset, NULL); -+ oscap_pcre_t *regex = oscap_pcre_compile("^(cpe:/o:microsoft:windows)(7.*)", 0, &pcreerror, &erroffset); -+ if (regex == NULL) { -+ oscap_pcre_err_free(pcreerror); -+ return; -+ } - int ovector[OVECTOR_LEN]; -- int rc = pcre_exec(regex, NULL, platform_idref, strlen(platform_idref), 0, 0, ovector, OVECTOR_LEN); -- pcre_free(regex); -+ int rc = oscap_pcre_exec(regex, platform_idref, strlen(platform_idref), 0, 0, ovector, OVECTOR_LEN); -+ oscap_pcre_free(regex); - /* 1 pattern + 2 groups = 3 */ - if (rc == 3) { - const int first_group_start = ovector[2]; -diff --git a/src/XCCDF_POLICY/xccdf_policy_remediate.c b/src/XCCDF_POLICY/xccdf_policy_remediate.c -index c5f81d3f0c6..9d4ba16e663 100644 ---- a/src/XCCDF_POLICY/xccdf_policy_remediate.c -+++ b/src/XCCDF_POLICY/xccdf_policy_remediate.c -@@ -38,12 +38,12 @@ - #endif - - #include --#include - - #include "XCCDF/item.h" - #include "common/_error.h" - #include "common/debug_priv.h" - #include "common/oscap_acquire.h" -+#include "common/oscap_pcre.h" - #include "xccdf_policy_priv.h" - #include "xccdf_policy_model_priv.h" - #include "public/xccdf_policy.h" -@@ -661,12 +661,12 @@ static int _write_fix_missing_warning_to_fd(const char *sys, int output_fd, stru - struct blueprint_entries { - const char *pattern; - struct oscap_list *list; -- pcre *re; -+ oscap_pcre_t *re; - }; - - static inline int _parse_blueprint_fix(const char *fix_text, struct oscap_list *generic, struct oscap_list *services_enable, struct oscap_list *services_disable, struct oscap_list *kernel_append) - { -- const char *err; -+ char *err; - int errofs; - int ret = 0; - -@@ -681,9 +681,10 @@ static inline int _parse_blueprint_fix(const char *fix_text, struct oscap_list * - }; - - for (int i = 0; tab[i].pattern != NULL; i++) { -- tab[i].re = pcre_compile(tab[i].pattern, PCRE_UTF8, &err, &errofs, NULL); -+ tab[i].re = oscap_pcre_compile(tab[i].pattern, OSCAP_PCRE_OPTS_UTF8, &err, &errofs); - if (tab[i].re == NULL) { -- dE("Unable to compile /%s/ regex pattern, pcre_compile() returned error (offset: %d): '%s'.\n", tab[i].pattern, errofs, err); -+ dE("Unable to compile /%s/ regex pattern, oscap_pcre_compile() returned error (offset: %d): '%s'.\n", tab[i].pattern, errofs, err); -+ oscap_pcre_err_free(err); - ret = 1; - goto exit; - } -@@ -695,7 +696,7 @@ static inline int _parse_blueprint_fix(const char *fix_text, struct oscap_list * - - for (int i = 0; tab[i].pattern != NULL; i++) { - while (true) { -- const int match = pcre_exec(tab[i].re, NULL, fix_text, fix_text_len, start_offset, -+ const int match = oscap_pcre_exec(tab[i].re, fix_text, fix_text_len, start_offset, - 0, ovector, sizeof(ovector) / sizeof(ovector[0])); - if (match == -1) - break; -@@ -726,7 +727,7 @@ static inline int _parse_blueprint_fix(const char *fix_text, struct oscap_list * - - exit: - for (int i = 0; tab[i].pattern != NULL; i++) -- pcre_free(tab[i].re); -+ oscap_pcre_free(tab[i].re); - - return ret; - } -@@ -737,13 +738,14 @@ static inline int _parse_ansible_fix(const char *fix_text, struct oscap_list *va - const char *pattern = - "- name: XCCDF Value [^ ]+ # promote to variable\n set_fact:\n" - " ([^:]+): (.+)\n tags:\n - always\n"; -- const char *err; -+ char *err; - int errofs; - -- pcre *re = pcre_compile(pattern, PCRE_UTF8, &err, &errofs, NULL); -+ oscap_pcre_t *re = oscap_pcre_compile(pattern, OSCAP_PCRE_OPTS_UTF8, &err, &errofs); - if (re == NULL) { - dE("Unable to compile regex pattern, " -- "pcre_compile() returned error (offset: %d): '%s'.\n", errofs, err); -+ "oscap_pcre_compile() returned error (offset: %d): '%s'.\n", errofs, err); -+ oscap_pcre_err_free(err); - return 1; - } - -@@ -758,14 +760,14 @@ static inline int _parse_ansible_fix(const char *fix_text, struct oscap_list *va - const size_t fix_text_len = strlen(fix_text); - int start_offset = 0; - while (true) { -- const int match = pcre_exec(re, NULL, fix_text, fix_text_len, start_offset, -+ const int match = oscap_pcre_exec(re, fix_text, fix_text_len, start_offset, - 0, ovector, sizeof(ovector) / sizeof(ovector[0])); - if (match == -1) - break; - if (match != 3) { - dE("Expected 2 capture group matches per XCCDF variable. Found %i!", - match - 1); -- pcre_free(re); -+ oscap_pcre_free(re); - return 1; - } - -@@ -807,7 +809,7 @@ static inline int _parse_ansible_fix(const char *fix_text, struct oscap_list *va - oscap_list_add(tasks, remediation_part); - } - -- pcre_free(re); -+ oscap_pcre_free(re); - return 0; - } - -diff --git a/src/common/util.c b/src/common/util.c -index 69e059a4c71..52362c098ae 100644 ---- a/src/common/util.c -+++ b/src/common/util.c -@@ -31,13 +31,13 @@ - #include - #include - #include --#include - #include - - #include "util.h" - #include "_error.h" - #include "oscap.h" - #include "oscap_helpers.h" -+#include "oscap_pcre.h" - #include "debug_priv.h" - - #ifdef OS_WINDOWS -@@ -361,7 +361,7 @@ char *oscap_path_join(const char *path1, const char *path2) - return joined_path; - } - --int oscap_get_substrings(char *str, int *ofs, pcre *re, int want_substrs, char ***substrings) { -+int oscap_get_substrings(char *str, int *ofs, oscap_pcre_t *re, int want_substrs, char ***substrings) { - int i, ret, rc; - int ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]); - char **substrs; -@@ -372,30 +372,26 @@ int oscap_get_substrings(char *str, int *ofs, pcre *re, int want_substrs, char * - ovector[i] = -1; - } - -- struct pcre_extra extra; -- extra.match_limit_recursion = OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT; -+ unsigned long limit = OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT; - char *limit_str = getenv("OSCAP_PCRE_EXEC_RECURSION_LIMIT"); -- if (limit_str != NULL) { -- unsigned long limit; -- if (sscanf(limit_str, "%lu", &limit) == 1) { -- extra.match_limit_recursion = limit; -- } -- } -- extra.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION; -+ if (limit_str != NULL) -+ if (sscanf(limit_str, "%lu", &limit) <= 0) -+ dW("Unable to parse OSCAP_PCRE_EXEC_RECURSION_LIMIT value"); -+ oscap_pcre_set_match_limit_recursion(re, limit); - size_t str_len = strlen(str); - #if defined(OS_SOLARIS) -- rc = pcre_exec(re, &extra, str, str_len, *ofs, PCRE_NO_UTF8_CHECK, ovector, ovector_len); -+ rc = oscap_pcre_exec(re, str, str_len, *ofs, OSCAP_PCRE_OPTS_NO_UTF8_CHECK, ovector, ovector_len); - #else -- rc = pcre_exec(re, &extra, str, str_len, *ofs, 0, ovector, ovector_len); -+ rc = oscap_pcre_exec(re, str, str_len, *ofs, 0, ovector, ovector_len); - #endif - -- if (rc < -1) { -+ if (rc < OSCAP_PCRE_ERR_NOMATCH) { - if (str_len < 100) -- dE("Function pcre_exec() failed to match a regular expression with return code %d on string '%s'.", rc, str); -+ dE("Function oscap_pcre_exec() failed to match a regular expression with return code %d on string '%s'.", rc, str); - else -- dE("Function pcre_exec() failed to match a regular expression with return code %d on string '%.100s' (truncated, showing first 100 characters).", rc, str); -+ dE("Function oscap_pcre_exec() failed to match a regular expression with return code %d on string '%.100s' (truncated, showing first 100 characters).", rc, str); - return rc; -- } else if (rc == -1) { -+ } else if (rc == OSCAP_PCRE_ERR_NOMATCH) { - /* no match */ - return 0; - } -diff --git a/src/common/util.h b/src/common/util.h -index 0db36fc31be..7f84e6436bc 100644 ---- a/src/common/util.h -+++ b/src/common/util.h -@@ -32,8 +32,8 @@ - #include "public/oscap.h" - #include - #include --#include - #include "oscap_export.h" -+#include "oscap_pcre.h" - - #ifndef __attribute__nonnull__ - #define __attribute__nonnull__(x) assert((x) != NULL) -@@ -498,7 +498,7 @@ char *oscap_strerror_r(int errnum, char *buf, size_t buflen); - * @return count of matched substrings, 0 if no match - * negative value on failure - */ --int oscap_get_substrings(char *str, int *ofs, pcre *re, int want_substrs, char ***substrings); -+int oscap_get_substrings(char *str, int *ofs, oscap_pcre_t *re, int want_substrs, char ***substrings); - - - #ifndef OS_WINDOWS -diff --git a/tests/API/OVAL/schema_version/test_schema_version.c b/tests/API/OVAL/schema_version/test_schema_version.c -index a282ece099d..d968f916a65 100644 ---- a/tests/API/OVAL/schema_version/test_schema_version.c -+++ b/tests/API/OVAL/schema_version/test_schema_version.c -@@ -27,6 +27,10 @@ - #include - #include - #include "OVAL/public/oval_schema_version.h" -+#include -+#include -+#include "util.h" -+#include "public/oscap_debug.h" - - static const char *cmp_to_cstr(int cmp) - { -@@ -44,6 +48,7 @@ int main(int argc, char **argv) - printf("Not enough arguments\n"); - return 1; - } -+ oscap_set_verbose(NULL, NULL); - const char *v1_str = argv[1]; - const char *v2_str = argv[2]; - int expected_result = atoi(argv[3]); -diff --git a/tests/API/XCCDF/unittests/CMakeLists.txt b/tests/API/XCCDF/unittests/CMakeLists.txt -index c9c507791ce..95441b40e1c 100644 ---- a/tests/API/XCCDF/unittests/CMakeLists.txt -+++ b/tests/API/XCCDF/unittests/CMakeLists.txt -@@ -4,6 +4,7 @@ add_oscap_test_executable(test_oscap_common - ${CMAKE_SOURCE_DIR}/src/common/list.c - ${CMAKE_SOURCE_DIR}/src/common/error.c - ${CMAKE_SOURCE_DIR}/src/common/err_queue.c -+ ${CMAKE_SOURCE_DIR}/src/common/oscap_pcre.c - ) - - add_oscap_test_executable(test_xccdf_overrides -diff --git a/tests/API/probes/CMakeLists.txt b/tests/API/probes/CMakeLists.txt -index 2ac4081ac27..cd5ca8358d3 100644 ---- a/tests/API/probes/CMakeLists.txt -+++ b/tests/API/probes/CMakeLists.txt -@@ -27,6 +27,7 @@ add_oscap_test_executable(oval_fts_list - "${CMAKE_SOURCE_DIR}/src/common/err_queue.c" - "${CMAKE_SOURCE_DIR}/src/OVAL/probes/probe/entcmp.c" - "${CMAKE_SOURCE_DIR}/src/common/util.c" -+ "${CMAKE_SOURCE_DIR}/src/common/oscap_pcre.c" - "${OVAL_RESULTS_SOURCES}" - ) - target_include_directories(oval_fts_list PUBLIC -diff --git a/tests/API/probes/oval_fts_list.c b/tests/API/probes/oval_fts_list.c -index eb1ffc283f0..e01526a89c4 100644 ---- a/tests/API/probes/oval_fts_list.c -+++ b/tests/API/probes/oval_fts_list.c -@@ -9,6 +9,10 @@ - #include "sexp.h" - #include "oval_fts.h" - #include "probe-api.h" -+#include -+#include -+#include "util.h" -+#include "public/oscap_debug.h" - - static int create_path_sexpr(char *arg_operation, char *arg_argument, SEXP_t **result) - { -@@ -172,6 +176,8 @@ int main(int argc, char *argv[]) - - int ret = 0; - -+ oscap_set_verbose(NULL, NULL); -+ - if (argc < 11) { - fprintf(stderr, "Invalid usage -- too few arguments supplied.\n"); - fprintf(stderr, "The following arguments are required, but may be empty:\n\n"); -diff --git a/tests/probes/textfilecontent54/test_recursion_limit.sh b/tests/probes/textfilecontent54/test_recursion_limit.sh -index 2619dafdd53..f34585dba60 100755 ---- a/tests/probes/textfilecontent54/test_recursion_limit.sh -+++ b/tests/probes/textfilecontent54/test_recursion_limit.sh -@@ -16,7 +16,7 @@ stderr=$(mktemp) - - $OSCAP oval eval --results $result $input > $stdout 2> $stderr - --grep -q "Function pcre_exec() failed to match a regular expression with return code -21" $stderr -+grep -q "Function oscap_pcre_exec() failed to match a regular expression with return code -21" $stderr - - assert_exists 1 '/oval_results/results/system/definitions/definition[@definition_id="oval:x:def:1" and @result="error"]' - -diff --git a/tests/probes/xinetd/CMakeLists.txt b/tests/probes/xinetd/CMakeLists.txt -index c2525277dde..f1bbbbc8bf2 100644 ---- a/tests/probes/xinetd/CMakeLists.txt -+++ b/tests/probes/xinetd/CMakeLists.txt -@@ -4,6 +4,7 @@ if(ENABLE_PROBES_UNIX) - "${CMAKE_SOURCE_DIR}/src/common/bfind.c" - "${CMAKE_SOURCE_DIR}/src/OVAL/probes/SEAP/generic/rbt/rbt_common.c" - "${CMAKE_SOURCE_DIR}/src/OVAL/probes/SEAP/generic/rbt/rbt_str.c" -+ "${CMAKE_SOURCE_DIR}/src/common/oscap_pcre.c" - ) - target_link_libraries(test_probe_xinetd openscap) - target_include_directories(test_probe_xinetd PUBLIC - -From f653e07627eea34de72ce6315af571ec4c54f10a Mon Sep 17 00:00:00 2001 -From: Evgeny Kolesnikov -Date: Mon, 4 Sep 2023 13:57:19 +0200 -Subject: [PATCH 3/4] Add PCRE2 library #3 - -Move the oscap_get_substring into the oscap_pcre.c module -and rename it into oscap_pcre_get_substring. - -The function imposes implicit dependencies on PCRE/PCRE2 symbols -even for utils.c users that won't use PCRE at all (SCE library). ---- - CMakeLists.txt | 1 + - .../independent/textfilecontent54_probe.c | 2 +- - .../independent/textfilecontent_probe.c | 2 +- - src/common/oscap_pcre.c | 71 +++++++++++++++++++ - src/common/oscap_pcre.h | 12 ++++ - src/common/util.c | 71 ------------------- - src/common/util.h | 14 ---- - 7 files changed, 86 insertions(+), 87 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index b6e5a825dc1..802f9d9a2a2 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -530,6 +530,7 @@ endif() - - if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -W -Wall -Wnonnull -Wshadow -Wformat -Wundef -Wno-unused-parameter -Wmissing-prototypes -Wno-unknown-pragmas -Wno-int-conversion -Werror=implicit-function-declaration -D_GNU_SOURCE -std=c99") -+ add_link_options(-Wl,-z,now) - endif() - if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") - add_link_options(-lkvm -lm -lprocstat) -diff --git a/src/OVAL/probes/independent/textfilecontent54_probe.c b/src/OVAL/probes/independent/textfilecontent54_probe.c -index af60cdf20a5..d3a5c6eb22c 100644 ---- a/src/OVAL/probes/independent/textfilecontent54_probe.c -+++ b/src/OVAL/probes/independent/textfilecontent54_probe.c -@@ -216,7 +216,7 @@ static int process_file(const char *prefix, const char *path, const char *file, - want_instance = 0; - - SEXP_free(next_inst); -- substr_cnt = oscap_get_substrings(buf, &ofs, pfd->compiled_regex, want_instance, &substrs); -+ substr_cnt = oscap_pcre_get_substrings(buf, &ofs, pfd->compiled_regex, want_instance, &substrs); - - if (substr_cnt < 0) { - SEXP_t *msg; -diff --git a/src/OVAL/probes/independent/textfilecontent_probe.c b/src/OVAL/probes/independent/textfilecontent_probe.c -index 224f0ea21a3..d4c1f62bd99 100644 ---- a/src/OVAL/probes/independent/textfilecontent_probe.c -+++ b/src/OVAL/probes/independent/textfilecontent_probe.c -@@ -196,7 +196,7 @@ static int process_file(const char *prefix, const char *path, const char *filena - int ofs = 0; - - while (fgets(line, sizeof(line), fp) != NULL) { -- substr_cnt = oscap_get_substrings(line, &ofs, re, 1, &substrs); -+ substr_cnt = oscap_pcre_get_substrings(line, &ofs, re, 1, &substrs); - if (substr_cnt > 0) { - int k; - SEXP_t *item; -diff --git a/src/common/oscap_pcre.c b/src/common/oscap_pcre.c -index d2e45292ab1..65694c44037 100644 ---- a/src/common/oscap_pcre.c -+++ b/src/common/oscap_pcre.c -@@ -26,6 +26,8 @@ - - #include - -+#define OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT 3500 -+ - #ifdef HAVE_PCRE2 - #define PCRE2_CODE_UNIT_WIDTH 8 - #define PCRE2_ERR_BUF_SIZE 127 -@@ -243,6 +245,75 @@ void oscap_pcre_free(oscap_pcre_t *opcre) - } - } - -+int oscap_pcre_get_substrings(char *str, int *ofs, oscap_pcre_t *re, int want_substrs, char ***substrings) { -+ int i, ret, rc; -+ int ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]); -+ char **substrs; -+ -+ // todo: max match count check -+ -+ for (i = 0; i < ovector_len; ++i) { -+ ovector[i] = -1; -+ } -+ -+ unsigned long limit = OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT; -+ char *limit_str = getenv("OSCAP_PCRE_EXEC_RECURSION_LIMIT"); -+ if (limit_str != NULL) -+ if (sscanf(limit_str, "%lu", &limit) <= 0) -+ dW("Unable to parse OSCAP_PCRE_EXEC_RECURSION_LIMIT value"); -+ oscap_pcre_set_match_limit_recursion(re, limit); -+ size_t str_len = strlen(str); -+#if defined(OS_SOLARIS) -+ rc = oscap_pcre_exec(re, str, str_len, *ofs, OSCAP_PCRE_OPTS_NO_UTF8_CHECK, ovector, ovector_len); -+#else -+ rc = oscap_pcre_exec(re, str, str_len, *ofs, 0, ovector, ovector_len); -+#endif -+ -+ if (rc < OSCAP_PCRE_ERR_NOMATCH) { -+ if (str_len < 100) -+ dE("Function oscap_pcre_exec() failed to match a regular expression with return code %d on string '%s'.", rc, str); -+ else -+ dE("Function oscap_pcre_exec() failed to match a regular expression with return code %d on string '%.100s' (truncated, showing first 100 characters).", rc, str); -+ return rc; -+ } else if (rc == OSCAP_PCRE_ERR_NOMATCH) { -+ /* no match */ -+ return 0; -+ } -+ -+ *ofs = (*ofs == ovector[1]) ? ovector[1] + 1 : ovector[1]; -+ -+ if (!want_substrs) { -+ /* just report successful match */ -+ return 1; -+ } -+ -+ ret = 0; -+ if (rc == 0) { -+ /* vector too small */ -+ // todo: report partial results -+ rc = ovector_len / 3; -+ } -+ -+ substrs = malloc(rc * sizeof (char *)); -+ for (i = 0; i < rc; ++i) { -+ int len; -+ char *buf; -+ -+ if (ovector[2 * i] == -1) { -+ continue; -+ } -+ len = ovector[2 * i + 1] - ovector[2 * i]; -+ buf = malloc(len + 1); -+ memcpy(buf, str + ovector[2 * i], len); -+ buf[len] = '\0'; -+ substrs[ret] = buf; -+ ++ret; -+ } -+ -+ *substrings = substrs; -+ -+ return ret; -+} - - void oscap_pcre_err_free(char *err) - { -diff --git a/src/common/oscap_pcre.h b/src/common/oscap_pcre.h -index df8acd01543..2f37955d8cb 100644 ---- a/src/common/oscap_pcre.h -+++ b/src/common/oscap_pcre.h -@@ -96,6 +96,18 @@ void oscap_pcre_set_match_limit_recursion(oscap_pcre_t *opcre, unsigned long lim - */ - void oscap_pcre_optimize(oscap_pcre_t *opcre); - -+/** -+ * Match a regular expression and return substrings. -+ * Caller is responsible for freeing the returned array. -+ * @param str subject string -+ * @param ofs starting offset in str -+ * @param re compiled regular expression -+ * @param want_substrs if non-zero, substrings will be returned -+ * @param substrings contains returned substrings -+ * @return count of matched substrings, 0 if no match -+ * negative value on failure -+ */ -+int oscap_pcre_get_substrings(char *str, int *ofs, oscap_pcre_t *re, int want_substrs, char ***substrings); - - /** - * Free the error message returned by oscap_pcre_compile. DON'T USE REGULAR free()! -diff --git a/src/common/util.c b/src/common/util.c -index 52362c098ae..8bce0d6a031 100644 ---- a/src/common/util.c -+++ b/src/common/util.c -@@ -49,7 +49,6 @@ - #endif - - #define PATH_SEPARATOR '/' --#define OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT 3500 - - int oscap_string_to_enum(const struct oscap_string_map *map, const char *str) - { -@@ -361,76 +360,6 @@ char *oscap_path_join(const char *path1, const char *path2) - return joined_path; - } - --int oscap_get_substrings(char *str, int *ofs, oscap_pcre_t *re, int want_substrs, char ***substrings) { -- int i, ret, rc; -- int ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]); -- char **substrs; -- -- // todo: max match count check -- -- for (i = 0; i < ovector_len; ++i) { -- ovector[i] = -1; -- } -- -- unsigned long limit = OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT; -- char *limit_str = getenv("OSCAP_PCRE_EXEC_RECURSION_LIMIT"); -- if (limit_str != NULL) -- if (sscanf(limit_str, "%lu", &limit) <= 0) -- dW("Unable to parse OSCAP_PCRE_EXEC_RECURSION_LIMIT value"); -- oscap_pcre_set_match_limit_recursion(re, limit); -- size_t str_len = strlen(str); --#if defined(OS_SOLARIS) -- rc = oscap_pcre_exec(re, str, str_len, *ofs, OSCAP_PCRE_OPTS_NO_UTF8_CHECK, ovector, ovector_len); --#else -- rc = oscap_pcre_exec(re, str, str_len, *ofs, 0, ovector, ovector_len); --#endif -- -- if (rc < OSCAP_PCRE_ERR_NOMATCH) { -- if (str_len < 100) -- dE("Function oscap_pcre_exec() failed to match a regular expression with return code %d on string '%s'.", rc, str); -- else -- dE("Function oscap_pcre_exec() failed to match a regular expression with return code %d on string '%.100s' (truncated, showing first 100 characters).", rc, str); -- return rc; -- } else if (rc == OSCAP_PCRE_ERR_NOMATCH) { -- /* no match */ -- return 0; -- } -- -- *ofs = (*ofs == ovector[1]) ? ovector[1] + 1 : ovector[1]; -- -- if (!want_substrs) { -- /* just report successful match */ -- return 1; -- } -- -- ret = 0; -- if (rc == 0) { -- /* vector too small */ -- // todo: report partial results -- rc = ovector_len / 3; -- } -- -- substrs = malloc(rc * sizeof (char *)); -- for (i = 0; i < rc; ++i) { -- int len; -- char *buf; -- -- if (ovector[2 * i] == -1) { -- continue; -- } -- len = ovector[2 * i + 1] - ovector[2 * i]; -- buf = malloc(len + 1); -- memcpy(buf, str + ovector[2 * i], len); -- buf[len] = '\0'; -- substrs[ret] = buf; -- ++ret; -- } -- -- *substrings = substrs; -- -- return ret; --} -- - #ifndef OS_WINDOWS - FILE *oscap_fopen_with_prefix(const char *prefix, const char *path) - { -diff --git a/src/common/util.h b/src/common/util.h -index 7f84e6436bc..0811a7698c1 100644 ---- a/src/common/util.h -+++ b/src/common/util.h -@@ -487,20 +487,6 @@ int oscap_strncasecmp(const char *s1, const char *s2, size_t n); - */ - char *oscap_strerror_r(int errnum, char *buf, size_t buflen); - --/** -- * Match a regular expression and return substrings. -- * Caller is responsible for freeing the returned array. -- * @param str subject string -- * @param ofs starting offset in str -- * @param re compiled regular expression -- * @param want_substrs if non-zero, substrings will be returned -- * @param substrings contains returned substrings -- * @return count of matched substrings, 0 if no match -- * negative value on failure -- */ --int oscap_get_substrings(char *str, int *ofs, oscap_pcre_t *re, int want_substrs, char ***substrings); -- -- - #ifndef OS_WINDOWS - /** - * Open file for reading with prefix added to its name. - diff --git a/openscap-1.3.10-fix_sysctl_probe_tests-PR-2050.patch b/openscap-1.3.10-fix_sysctl_probe_tests-PR-2050.patch new file mode 100644 index 0000000..b0f28e7 --- /dev/null +++ b/openscap-1.3.10-fix_sysctl_probe_tests-PR-2050.patch @@ -0,0 +1,165 @@ +From f8366b395b977392d724c6cc84c7295590c39ee8 Mon Sep 17 00:00:00 2001 +From: Evgeny Kolesnikov +Date: Tue, 7 Nov 2023 20:01:44 +0100 +Subject: [PATCH] Fix tests/probes/sysctl_all + +The test will now automatically adapt to the list of readable +variables and won't break every time a new root-readable variable +is introduced in kernel. +--- + tests/probes/sysctl/test_sysctl_probe_all.sh | 144 +++++++------------ + 1 file changed, 50 insertions(+), 94 deletions(-) + +diff --git a/tests/probes/sysctl/test_sysctl_probe_all.sh b/tests/probes/sysctl/test_sysctl_probe_all.sh +index f1834059fb..efaa31b9b1 100755 +--- a/tests/probes/sysctl/test_sysctl_probe_all.sh ++++ b/tests/probes/sysctl/test_sysctl_probe_all.sh +@@ -8,98 +8,57 @@ set -e -o pipefail + # non root users + PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin + +-# non root users are not able to access some kernel params, so they get excluded +-SYSCTL_EXCLUDE=' +- dev.parport.parport0.autoprobe +- dev.tty.legacy_tiocsti +- fs.protected_hardlinks +- fs.protected_fifos +- fs.protected_regular +- fs.protected_symlinks +- kernel.cad_pid +- kernel.unprivileged_userns_apparmor_policy +- kernel.apparmor_display_secid_mode +- kernel.usermodehelper.bset +- kernel.usermodehelper.inheritable +- net.core.bpf_jit_harden +- net.core.bpf_jit_kallsyms +- net.core.bpf_jit_limit +- net.ipv4.tcp_fastopen_key +- stable_secret +- vm.mmap_rnd_bits +- vm.mmap_rnd_compat_bits +- vm.stat_refresh' +- +-SYSCTL_EXCLUDE_REGEX="$(printf '\|%s' $SYSCTL_EXCLUDE)" +-# strip leading '\|' +-SYSCTL_EXCLUDE_REGEX=${SYSCTL_EXCLUDE_REGEX:2} +- + function perform_test { +-probecheck "sysctl" || return 255 +- +-name=$(basename $0 .sh) +- +-result=$(mktemp ${name}.res.out.XXXXXX) +-stderr=$(mktemp ${name}.err.out.XXXXXX) +-ourNames=$(mktemp ${name}.our.out.XXXXXX) +-sysctlNames=$(mktemp ${name}.sysctl.out.XXXXXX) +- +-echo "Result file: $result" +-echo "Our names file: $ourNames" +-echo "Sysctl names file: $sysctlNames" +-echo "Errors file: $stderr" +- +-$OSCAP oval eval --results $result $srcdir/test_sysctl_probe_all.oval.xml > /dev/null 2>$stderr +- +-case $(uname) in +- FreeBSD) +- sysctl -aN 2> /dev/null > "$sysctlNames" +- ;; +- Linux) +- # sysctl has duplicities in output +- # hide permission errors like: "sysctl: permission denied on key 'fs.protected_hardlinks'" +- # kernel parameters might use "/" and "." separators interchangeably - normalizing +- sysctl -aN --deprecated 2> /dev/null | grep -v $SYSCTL_EXCLUDE_REGEX | tr "/" "." | sort -u > "$sysctlNames" +- ;; +-esac +- +-grep unix-sys:name "$result" | grep -v $SYSCTL_EXCLUDE_REGEX | xsed -E 's;.*>(.*)<.*;\1;g' | sort > "$ourNames" +- +-# If procps_ver > 3.3.12 we need to filter *stable_secret and vm.stat_refresh +-# options from the sysctl output, for more details see +-# https://github.com/OpenSCAP/openscap/issues/1152. +-procps_ver="$(package_version procps-ng procps)" +- +-lowest_ver=$(echo -e "3.3.12\n$procps_ver" | sort -V | head -n1) +-if [ "$procps_ver" != "$lowest_ver" ]; then +- sed -i '/net.ipv6.conf.*stable_secret$/d' "$sysctlNames" +- sed -i '/.*vm.stat_refresh/d' "$sysctlNames" +-fi +- +-if ! grep -q "hugepages" "$ourNames"; then +- sed -i "/^.*hugepages.*$/d" "$sysctlNames" +-fi +- +-echo "Diff (sysctlNames / ourNames): ------" +-diff "$sysctlNames" "$ourNames" +-echo "-------------------------------------" +- +-# remove oscap error message related to permissions from stderr +-sed -i -E "/^E: oscap: +Can't read sysctl value from /d" "$stderr" +-sed -i -E "/^E: oscap: +An error.*, Operation not permitted/d" "$stderr" +- +-# remove oscap error message related to gibberish binary entries +-# that can't fit into 8K buffer and result in errno 14 +-# (for example /proc/sys/kernel/spl/hostid could be the case) +-sed -i -E "/^E: oscap: +An error.*14, Bad address/d" "$stderr" +-sed -i "/^.*hugepages.*$/d" "$stderr" +- +-echo "Errors (without messages related to permissions):" +-cat "$stderr" +- +-[ ! -s $stderr ] +- +-rm $stderr $result $ourNames $sysctlNames ++ probecheck "sysctl" || return 255 ++ ++ name=$(basename $0 .sh) ++ ++ result=$(mktemp ${name}.res.out.XXXXXX) ++ stderr=$(mktemp ${name}.err.out.XXXXXX) ++ ourNames=$(mktemp ${name}.our.out.XXXXXX) ++ sysctlNames=$(mktemp ${name}.sysctl.out.XXXXXX) ++ ++ echo "Result file: $result" ++ echo "Our names file: $ourNames" ++ echo "Sysctl names file: $sysctlNames" ++ echo "Errors file: $stderr" ++ ++ $OSCAP oval eval --results $result $srcdir/test_sysctl_probe_all.oval.xml > /dev/null 2>$stderr ++ ++ case $(uname) in ++ FreeBSD) ++ sysctl -aN 2> /dev/null > "$sysctlNames" ++ ;; ++ Linux) ++ # sysctl has duplicities in output ++ # hide permission errors like: "sysctl: permission denied on key 'fs.protected_hardlinks'" ++ # kernel parameters might use "/" and "." separators interchangeably - normalizing ++ sysctl -a --deprecated 2> /dev/null | tr "/" "." | cut -d "=" -f 1 | tr -d " " | sort -u > "$sysctlNames" ++ ;; ++ esac ++ ++ grep unix-sys:name "$result" | xsed -E 's;.*>(.*)<.*;\1;g' | sort > "$ourNames" ++ ++ echo "Diff (sysctlNames / ourNames): ------" ++ diff "$sysctlNames" "$ourNames" ++ echo "-------------------------------------" ++ ++ # remove oscap error message related to permissions from stderr ++ sed -i -E "/^E: oscap: +Can't read sysctl value from /d" "$stderr" ++ sed -i -E "/^E: oscap: +An error.*, Operation not permitted/d" "$stderr" ++ ++ # remove oscap error message related to gibberish binary entries ++ # that can't fit into 8K buffer and result in errno 14 ++ # (for example /proc/sys/kernel/spl/hostid could be the case) ++ sed -i -E "/^E: oscap: +An error.*14, Bad address/d" "$stderr" ++ sed -i "/^.*hugepages.*$/d" "$stderr" ++ ++ echo "Errors (without messages related to permissions):" ++ cat "$stderr" ++ ++ [ ! -s $stderr ] ++ ++ rm $stderr $result $ourNames $sysctlNames + } + + perform_test diff --git a/openscap.spec b/openscap.spec index b4d27c3..7394c36 100644 --- a/openscap.spec +++ b/openscap.spec @@ -1,6 +1,6 @@ Name: openscap Version: 1.3.9 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 1 Summary: Set of open source libraries enabling integration of the SCAP line of standards License: LGPL-2.1-or-later @@ -10,10 +10,6 @@ Source0: https://github.com/OpenSCAP/%{name}/releases/download/%{version} %bcond_without check -# merged to 1.3.9 -# port to PCRE2 (PR#2015), minus CI-specific changes -# Patch0: 2015.patch - # Fedora arched lib directories # https://github.com/OpenSCAP/openscap/pull/2056 Patch1: openscap-1.3.9-perlpath.patch @@ -23,6 +19,9 @@ Patch1: openscap-1.3.9-perlpath.patch # reported in #PR2060, #PR2061, #PR2062 Patch2: openscap-1.3.9-includes.patch +# Fix test test_sysctl_probe_all.sh +Patch3: openscap-1.3.10-fix_sysctl_probe_tests-PR-2050.patch + BuildRequires: make BuildRequires: cmake >= 2.6 BuildRequires: gcc @@ -276,6 +275,10 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' %{_mandir}/man8/oscap-podman.8* %changelog +* Wed Dec 20 2023 Jan Černý - 1:1.3.9-3 +- Fix test test_sysctl_probe_all.sh +- Clean up the repository + * Thu Nov 23 2023 Michal Ambroz - 1:1.3.9-2 - adding conditional for apt-devel apt-libs as proposed upstream