|
|
0b628f |
diff --git a/docs/developer/developer.adoc b/docs/developer/developer.adoc
|
|
|
0b628f |
index 08273e24d..823a1504e 100644
|
|
|
0b628f |
--- a/docs/developer/developer.adoc
|
|
|
0b628f |
+++ b/docs/developer/developer.adoc
|
|
|
0b628f |
@@ -317,6 +317,8 @@ behaviour.
|
|
|
0b628f |
|
|
|
0b628f |
* *OSCAP_FULL_VALIDATION=1* - validate all exported documents (slower)
|
|
|
0b628f |
* *SEXP_VALIDATE_DISABLE=1* - do not validate SEXP expressions (faster)
|
|
|
0b628f |
+* *OSCAP_PCRE_EXEC_RECURSION_LIMIT* - override default recursion limit
|
|
|
0b628f |
+ for match in pcre_exec call in textfilecontent(54) probes.
|
|
|
0b628f |
|
|
|
0b628f |
|
|
|
0b628f |
|
|
|
0b628f |
diff --git a/src/OVAL/probes/independent/textfilecontent54_probe.c b/src/OVAL/probes/independent/textfilecontent54_probe.c
|
|
|
0b628f |
index 1c449833f..3053f5d95 100644
|
|
|
0b628f |
--- a/src/OVAL/probes/independent/textfilecontent54_probe.c
|
|
|
0b628f |
+++ b/src/OVAL/probes/independent/textfilecontent54_probe.c
|
|
|
0b628f |
@@ -52,68 +52,11 @@
|
|
|
0b628f |
#include <probe/option.h>
|
|
|
0b628f |
#include <oval_fts.h>
|
|
|
0b628f |
#include "common/debug_priv.h"
|
|
|
0b628f |
+#include "common/util.h"
|
|
|
0b628f |
#include "textfilecontent54_probe.h"
|
|
|
0b628f |
|
|
|
0b628f |
#define FILE_SEPARATOR '/'
|
|
|
0b628f |
|
|
|
0b628f |
-static int get_substrings(char *str, int *ofs, pcre *re, int want_substrs, char ***substrings) {
|
|
|
0b628f |
- int i, ret, rc;
|
|
|
0b628f |
- int ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]);
|
|
|
0b628f |
- char **substrs;
|
|
|
0b628f |
-
|
|
|
0b628f |
- // todo: max match count check
|
|
|
0b628f |
-
|
|
|
0b628f |
- for (i = 0; i < ovector_len; ++i)
|
|
|
0b628f |
- ovector[i] = -1;
|
|
|
0b628f |
-
|
|
|
0b628f |
-#if defined(OS_SOLARIS)
|
|
|
0b628f |
- rc = pcre_exec(re, NULL, str, strlen(str), *ofs, PCRE_NO_UTF8_CHECK, ovector, ovector_len);
|
|
|
0b628f |
-#else
|
|
|
0b628f |
- rc = pcre_exec(re, NULL, str, strlen(str), *ofs, 0, ovector, ovector_len);
|
|
|
0b628f |
-#endif
|
|
|
0b628f |
-
|
|
|
0b628f |
- if (rc < -1) {
|
|
|
0b628f |
- dE("Function pcre_exec() failed to match a regular expression with return code %d on string '%s'.", rc, str);
|
|
|
0b628f |
- return rc;
|
|
|
0b628f |
- } else if (rc == -1) {
|
|
|
0b628f |
- /* no match */
|
|
|
0b628f |
- return 0;
|
|
|
0b628f |
- }
|
|
|
0b628f |
-
|
|
|
0b628f |
- *ofs = (*ofs == ovector[1]) ? ovector[1] + 1 : ovector[1];
|
|
|
0b628f |
-
|
|
|
0b628f |
- if (!want_substrs) {
|
|
|
0b628f |
- /* just report successful match */
|
|
|
0b628f |
- return 1;
|
|
|
0b628f |
- }
|
|
|
0b628f |
-
|
|
|
0b628f |
- ret = 0;
|
|
|
0b628f |
- if (rc == 0) {
|
|
|
0b628f |
- /* vector too small */
|
|
|
0b628f |
- // todo: report partial results
|
|
|
0b628f |
- rc = ovector_len / 3;
|
|
|
0b628f |
- }
|
|
|
0b628f |
-
|
|
|
0b628f |
- substrs = malloc(rc * sizeof (char *));
|
|
|
0b628f |
- for (i = 0; i < rc; ++i) {
|
|
|
0b628f |
- int len;
|
|
|
0b628f |
- char *buf;
|
|
|
0b628f |
-
|
|
|
0b628f |
- if (ovector[2 * i] == -1)
|
|
|
0b628f |
- continue;
|
|
|
0b628f |
- len = ovector[2 * i + 1] - ovector[2 * i];
|
|
|
0b628f |
- buf = malloc(len + 1);
|
|
|
0b628f |
- memcpy(buf, str + ovector[2 * i], len);
|
|
|
0b628f |
- buf[len] = '\0';
|
|
|
0b628f |
- substrs[ret] = buf;
|
|
|
0b628f |
- ++ret;
|
|
|
0b628f |
- }
|
|
|
0b628f |
-
|
|
|
0b628f |
- *substrings = substrs;
|
|
|
0b628f |
-
|
|
|
0b628f |
- return ret;
|
|
|
0b628f |
-}
|
|
|
0b628f |
-
|
|
|
0b628f |
static SEXP_t *create_item(const char *path, const char *filename, char *pattern,
|
|
|
0b628f |
int instance, char **substrs, int substr_cnt, oval_schema_version_t over)
|
|
|
0b628f |
{
|
|
|
0b628f |
@@ -260,7 +203,7 @@ static int process_file(const char *prefix, const char *path, const char *file,
|
|
|
0b628f |
want_instance = 0;
|
|
|
0b628f |
|
|
|
0b628f |
SEXP_free(next_inst);
|
|
|
0b628f |
- substr_cnt = get_substrings(buf, &ofs, pfd->compiled_regex, want_instance, &substrs);
|
|
|
0b628f |
+ substr_cnt = oscap_get_substrings(buf, &ofs, pfd->compiled_regex, want_instance, &substrs);
|
|
|
0b628f |
|
|
|
0b628f |
if (substr_cnt < 0) {
|
|
|
0b628f |
SEXP_t *msg;
|
|
|
0b628f |
diff --git a/src/OVAL/probes/independent/textfilecontent_probe.c b/src/OVAL/probes/independent/textfilecontent_probe.c
|
|
|
0b628f |
index 9abf8fcc3..988a6471d 100644
|
|
|
0b628f |
--- a/src/OVAL/probes/independent/textfilecontent_probe.c
|
|
|
0b628f |
+++ b/src/OVAL/probes/independent/textfilecontent_probe.c
|
|
|
0b628f |
@@ -71,63 +71,11 @@
|
|
|
0b628f |
#include <probe/option.h>
|
|
|
0b628f |
#include <oval_fts.h>
|
|
|
0b628f |
#include "common/debug_priv.h"
|
|
|
0b628f |
+#include "common/util.h"
|
|
|
0b628f |
#include "textfilecontent_probe.h"
|
|
|
0b628f |
|
|
|
0b628f |
#define FILE_SEPARATOR '/'
|
|
|
0b628f |
|
|
|
0b628f |
-static int get_substrings(char *str, pcre *re, int want_substrs, char ***substrings) {
|
|
|
0b628f |
- int i, ret, rc;
|
|
|
0b628f |
- int ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]);
|
|
|
0b628f |
-
|
|
|
0b628f |
- // todo: max match count check
|
|
|
0b628f |
-
|
|
|
0b628f |
- for (i = 0; i < ovector_len; ++i)
|
|
|
0b628f |
- ovector[i] = -1;
|
|
|
0b628f |
-
|
|
|
0b628f |
- rc = pcre_exec(re, NULL, str, strlen(str), 0, 0,
|
|
|
0b628f |
- ovector, ovector_len);
|
|
|
0b628f |
-
|
|
|
0b628f |
- if (rc < -1) {
|
|
|
0b628f |
- return -1;
|
|
|
0b628f |
- } else if (rc == -1) {
|
|
|
0b628f |
- /* no match */
|
|
|
0b628f |
- return 0;
|
|
|
0b628f |
- } else if(!want_substrs) {
|
|
|
0b628f |
- /* just report successful match */
|
|
|
0b628f |
- return 1;
|
|
|
0b628f |
- }
|
|
|
0b628f |
-
|
|
|
0b628f |
- char **substrs;
|
|
|
0b628f |
-
|
|
|
0b628f |
- ret = 0;
|
|
|
0b628f |
- if (rc == 0) {
|
|
|
0b628f |
- /* vector too small */
|
|
|
0b628f |
- rc = ovector_len / 3;
|
|
|
0b628f |
- }
|
|
|
0b628f |
-
|
|
|
0b628f |
- substrs = malloc(rc * sizeof (char *));
|
|
|
0b628f |
- for (i = 0; i < rc; ++i) {
|
|
|
0b628f |
- int len;
|
|
|
0b628f |
- char *buf;
|
|
|
0b628f |
-
|
|
|
0b628f |
- if (ovector[2 * i] == -1)
|
|
|
0b628f |
- continue;
|
|
|
0b628f |
- len = ovector[2 * i + 1] - ovector[2 * i];
|
|
|
0b628f |
- buf = malloc(len + 1);
|
|
|
0b628f |
- memcpy(buf, str + ovector[2 * i], len);
|
|
|
0b628f |
- buf[len] = '\0';
|
|
|
0b628f |
- substrs[ret] = buf;
|
|
|
0b628f |
- ++ret;
|
|
|
0b628f |
- }
|
|
|
0b628f |
- /*
|
|
|
0b628f |
- if (ret < rc)
|
|
|
0b628f |
- substrs = realloc(substrs, ret * sizeof (char *));
|
|
|
0b628f |
- */
|
|
|
0b628f |
- *substrings = substrs;
|
|
|
0b628f |
-
|
|
|
0b628f |
- return ret;
|
|
|
0b628f |
-}
|
|
|
0b628f |
-
|
|
|
0b628f |
static SEXP_t *create_item(const char *path, const char *filename, char *pattern,
|
|
|
0b628f |
int instance, char **substrs, int substr_cnt, oval_schema_version_t over)
|
|
|
0b628f |
{
|
|
|
0b628f |
@@ -244,9 +192,10 @@ static int process_file(const char *prefix, const char *path, const char *filena
|
|
|
0b628f |
|
|
|
0b628f |
int cur_inst = 0;
|
|
|
0b628f |
char line[4096];
|
|
|
0b628f |
+ int ofs = 0;
|
|
|
0b628f |
|
|
|
0b628f |
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
|
0b628f |
- substr_cnt = get_substrings(line, re, 1, &substrs);
|
|
|
0b628f |
+ substr_cnt = oscap_get_substrings(line, &ofs, re, 1, &substrs);
|
|
|
0b628f |
if (substr_cnt > 0) {
|
|
|
0b628f |
int k;
|
|
|
0b628f |
SEXP_t *item;
|
|
|
0b628f |
diff --git a/src/common/util.c b/src/common/util.c
|
|
|
0b628f |
index 146b7bc39..8f130c50e 100644
|
|
|
0b628f |
--- a/src/common/util.c
|
|
|
0b628f |
+++ b/src/common/util.c
|
|
|
0b628f |
@@ -30,11 +30,13 @@
|
|
|
0b628f |
#include <limits.h>
|
|
|
0b628f |
#include <stdarg.h>
|
|
|
0b628f |
#include <math.h>
|
|
|
0b628f |
+#include <pcre.h>
|
|
|
0b628f |
|
|
|
0b628f |
#include "util.h"
|
|
|
0b628f |
#include "_error.h"
|
|
|
0b628f |
#include "oscap.h"
|
|
|
0b628f |
#include "oscap_helpers.h"
|
|
|
0b628f |
+#include "debug_priv.h"
|
|
|
0b628f |
|
|
|
0b628f |
#ifdef OS_WINDOWS
|
|
|
0b628f |
#include <stdlib.h>
|
|
|
0b628f |
@@ -45,6 +47,7 @@
|
|
|
0b628f |
#endif
|
|
|
0b628f |
|
|
|
0b628f |
#define PATH_SEPARATOR '/'
|
|
|
0b628f |
+#define OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT 5000
|
|
|
0b628f |
|
|
|
0b628f |
int oscap_string_to_enum(const struct oscap_string_map *map, const char *str)
|
|
|
0b628f |
{
|
|
|
0b628f |
@@ -353,6 +356,76 @@ char *oscap_path_join(const char *path1, const char *path2)
|
|
|
0b628f |
return joined_path;
|
|
|
0b628f |
}
|
|
|
0b628f |
|
|
|
0b628f |
+int oscap_get_substrings(char *str, int *ofs, pcre *re, int want_substrs, char ***substrings) {
|
|
|
0b628f |
+ int i, ret, rc;
|
|
|
0b628f |
+ int ovector[60], ovector_len = sizeof (ovector) / sizeof (ovector[0]);
|
|
|
0b628f |
+ char **substrs;
|
|
|
0b628f |
+
|
|
|
0b628f |
+ // todo: max match count check
|
|
|
0b628f |
+
|
|
|
0b628f |
+ for (i = 0; i < ovector_len; ++i) {
|
|
|
0b628f |
+ ovector[i] = -1;
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+
|
|
|
0b628f |
+ struct pcre_extra extra;
|
|
|
0b628f |
+ extra.match_limit_recursion = OSCAP_PCRE_EXEC_RECURSION_LIMIT_DEFAULT;
|
|
|
0b628f |
+ char *limit_str = getenv("OSCAP_PCRE_EXEC_RECURSION_LIMIT");
|
|
|
0b628f |
+ if (limit_str != NULL) {
|
|
|
0b628f |
+ unsigned long limit;
|
|
|
0b628f |
+ if (sscanf(limit_str, "%lu", &limit) == 1) {
|
|
|
0b628f |
+ extra.match_limit_recursion = limit;
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+ extra.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION;
|
|
|
0b628f |
+#if defined(OS_SOLARIS)
|
|
|
0b628f |
+ rc = pcre_exec(re, &extra, str, strlen(str), *ofs, PCRE_NO_UTF8_CHECK, ovector, ovector_len);
|
|
|
0b628f |
+#else
|
|
|
0b628f |
+ rc = pcre_exec(re, &extra, str, strlen(str), *ofs, 0, ovector, ovector_len);
|
|
|
0b628f |
+#endif
|
|
|
0b628f |
+
|
|
|
0b628f |
+ if (rc < -1) {
|
|
|
0b628f |
+ dE("Function pcre_exec() failed to match a regular expression with return code %d on string '%s'.", rc, str);
|
|
|
0b628f |
+ return rc;
|
|
|
0b628f |
+ } else if (rc == -1) {
|
|
|
0b628f |
+ /* no match */
|
|
|
0b628f |
+ return 0;
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+
|
|
|
0b628f |
+ *ofs = (*ofs == ovector[1]) ? ovector[1] + 1 : ovector[1];
|
|
|
0b628f |
+
|
|
|
0b628f |
+ if (!want_substrs) {
|
|
|
0b628f |
+ /* just report successful match */
|
|
|
0b628f |
+ return 1;
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+
|
|
|
0b628f |
+ ret = 0;
|
|
|
0b628f |
+ if (rc == 0) {
|
|
|
0b628f |
+ /* vector too small */
|
|
|
0b628f |
+ // todo: report partial results
|
|
|
0b628f |
+ rc = ovector_len / 3;
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+
|
|
|
0b628f |
+ substrs = malloc(rc * sizeof (char *));
|
|
|
0b628f |
+ for (i = 0; i < rc; ++i) {
|
|
|
0b628f |
+ int len;
|
|
|
0b628f |
+ char *buf;
|
|
|
0b628f |
+
|
|
|
0b628f |
+ if (ovector[2 * i] == -1) {
|
|
|
0b628f |
+ continue;
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+ len = ovector[2 * i + 1] - ovector[2 * i];
|
|
|
0b628f |
+ buf = malloc(len + 1);
|
|
|
0b628f |
+ memcpy(buf, str + ovector[2 * i], len);
|
|
|
0b628f |
+ buf[len] = '\0';
|
|
|
0b628f |
+ substrs[ret] = buf;
|
|
|
0b628f |
+ ++ret;
|
|
|
0b628f |
+ }
|
|
|
0b628f |
+
|
|
|
0b628f |
+ *substrings = substrs;
|
|
|
0b628f |
+
|
|
|
0b628f |
+ return ret;
|
|
|
0b628f |
+}
|
|
|
0b628f |
+
|
|
|
0b628f |
#ifdef OS_WINDOWS
|
|
|
0b628f |
char *oscap_windows_wstr_to_str(const wchar_t *wstr)
|
|
|
0b628f |
{
|
|
|
0b628f |
diff --git a/src/common/util.h b/src/common/util.h
|
|
|
0b628f |
index 50a1c746f..2592f3962 100644
|
|
|
0b628f |
--- a/src/common/util.h
|
|
|
0b628f |
+++ b/src/common/util.h
|
|
|
0b628f |
@@ -31,6 +31,7 @@
|
|
|
0b628f |
#include "public/oscap.h"
|
|
|
0b628f |
#include <stdarg.h>
|
|
|
0b628f |
#include <string.h>
|
|
|
0b628f |
+#include <pcre.h>
|
|
|
0b628f |
#include "oscap_export.h"
|
|
|
0b628f |
|
|
|
0b628f |
#ifndef __attribute__nonnull__
|
|
|
0b628f |
@@ -467,6 +468,19 @@ int oscap_strncasecmp(const char *s1, const char *s2, size_t n);
|
|
|
0b628f |
*/
|
|
|
0b628f |
char *oscap_strerror_r(int errnum, char *buf, size_t buflen);
|
|
|
0b628f |
|
|
|
0b628f |
+/**
|
|
|
0b628f |
+ * Match a regular expression and return substrings.
|
|
|
0b628f |
+ * Caller is responsible for freeing the returned array.
|
|
|
0b628f |
+ * @param str subject string
|
|
|
0b628f |
+ * @param ofs starting offset in str
|
|
|
0b628f |
+ * @param re compiled regular expression
|
|
|
0b628f |
+ * @param want_substrs if non-zero, substrings will be returned
|
|
|
0b628f |
+ * @param substrings contains returned substrings
|
|
|
0b628f |
+ * @return count of matched substrings, 0 if no match
|
|
|
0b628f |
+ * negative value on failure
|
|
|
0b628f |
+ */
|
|
|
0b628f |
+int oscap_get_substrings(char *str, int *ofs, pcre *re, int want_substrs, char ***substrings);
|
|
|
0b628f |
+
|
|
|
0b628f |
#ifdef OS_WINDOWS
|
|
|
0b628f |
/**
|
|
|
0b628f |
* Convert wide character string to a C string (UTF-16 to UTF-8)
|
|
|
0b628f |
diff --git a/tests/probes/textfilecontent54/30-ospp-v42.rules b/tests/probes/textfilecontent54/30-ospp-v42.rules
|
|
|
0b628f |
new file mode 100644
|
|
|
0b628f |
index 000000000..7ad0c254d
|
|
|
0b628f |
--- /dev/null
|
|
|
0b628f |
+++ b/tests/probes/textfilecontent54/30-ospp-v42.rules
|
|
|
0b628f |
@@ -0,0 +1,113 @@
|
|
|
0b628f |
+## The purpose of these rules is to meet the requirements for Operating
|
|
|
0b628f |
+## System Protection Profile (OSPP)v4.2. These rules depends on having
|
|
|
0b628f |
+## 10-base-config.rules, 11-loginuid.rules, and 43-module-load.rules installed.
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Unsuccessful file creation (open with O_CREAT)
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Unsuccessful file modifications (open for write or truncate)
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Unsuccessful file access (any other opens) This has to go last.
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Unsuccessful file delete
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-delete
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-delete
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-delete
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-delete
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Unsuccessful permission change
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat,setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat,setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat,setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat,setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Unsuccessful ownership change
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S lchown,fchown,chown,fchownat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S lchown,fchown,chown,fchownat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-perm-change
|
|
|
0b628f |
+
|
|
|
0b628f |
+## User add delete modify. This is covered by pam. However, someone could
|
|
|
0b628f |
+## open a file and directly create or modify a user, so we'll watch passwd and
|
|
|
0b628f |
+## shadow for writes
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&03 -F path=/etc/passwd -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&03 -F path=/etc/passwd -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&03 -F path=/etc/passwd -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&03 -F path=/etc/passwd -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&03 -F path=/etc/shadow -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&03 -F path=/etc/shadow -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&03 -F path=/etc/shadow -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&03 -F path=/etc/shadow -F auid>=1000 -F auid!=unset -F key=user-modify
|
|
|
0b628f |
+
|
|
|
0b628f |
+## User enable and disable. This is entirely handled by pam.
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Group add delete modify. This is covered by pam. However, someone could
|
|
|
0b628f |
+## open a file and directly create or modify a user, so we'll watch group and
|
|
|
0b628f |
+## gshadow for writes
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&03 -F path=/etc/group -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&03 -F path=/etc/group -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&03 -F path=/etc/group -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&03 -F path=/etc/group -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&03 -F path=/etc/gshadow -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&03 -F path=/etc/gshadow -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+-a always,exit -F arch=b32 -S open -F a1&03 -F path=/etc/gshadow -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+-a always,exit -F arch=b64 -S open -F a1&03 -F path=/etc/gshadow -F auid>=1000 -F auid!=unset -F key=group-modify
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Use of special rights for config changes. This would be use of setuid
|
|
|
0b628f |
+## programs that relate to user accts. This is not all setuid apps because
|
|
|
0b628f |
+## requirements are only for ones that affect system configuration.
|
|
|
0b628f |
+-a always,exit -F path=/usr/sbin/usernetctl -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/sbin/seunshare -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/mount -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/newgrp -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/newuidmap -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/gpasswd -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/newgidmap -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/umount -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/passwd -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/crontab -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+-a always,exit -F path=/usr/bin/at -F perm=x -F auid>=1000 -F auid!=unset -F key=special-config-changes
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Privilege escalation via su or sudo. This is entirely handled by pam.
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Audit log access
|
|
|
0b628f |
+-a always,exit -F dir=/var/log/audit/ -F perm=r -F auid>=1000 -F auid!=unset -F key=access-audit-trail
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Software updates. This is entirely handled by rpm.
|
|
|
0b628f |
+
|
|
|
0b628f |
+## System start and shutdown. This is entirely handled by systemd
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Kernel Module loading. This is handled in 43-module-load.rules
|
|
|
0b628f |
+
|
|
|
0b628f |
+## Application invocation. The requirements list an optional requirement
|
|
|
0b628f |
+## FPT_SRP_EXT.1 Software Restriction Policies. This event is intended to
|
|
|
0b628f |
+## state results from that policy. This would be handled entirely by
|
|
|
0b628f |
+## that daemon.
|
|
|
0b628f |
+
|
|
|
0b628f |
diff --git a/tests/probes/textfilecontent54/CMakeLists.txt b/tests/probes/textfilecontent54/CMakeLists.txt
|
|
|
0b628f |
index 87c6e215d..48bbde0e6 100644
|
|
|
0b628f |
--- a/tests/probes/textfilecontent54/CMakeLists.txt
|
|
|
0b628f |
+++ b/tests/probes/textfilecontent54/CMakeLists.txt
|
|
|
0b628f |
@@ -1,4 +1,5 @@
|
|
|
0b628f |
if(ENABLE_PROBES_INDEPENDENT)
|
|
|
0b628f |
add_oscap_test("all.sh")
|
|
|
0b628f |
add_oscap_test("test_filecontent_non_utf.sh")
|
|
|
0b628f |
+ add_oscap_test("test_recursion_limit.sh")
|
|
|
0b628f |
endif()
|
|
|
0b628f |
diff --git a/tests/probes/textfilecontent54/test_recursion_limit.oval.xml b/tests/probes/textfilecontent54/test_recursion_limit.oval.xml
|
|
|
0b628f |
new file mode 100644
|
|
|
0b628f |
index 000000000..6f6a5ba14
|
|
|
0b628f |
--- /dev/null
|
|
|
0b628f |
+++ b/tests/probes/textfilecontent54/test_recursion_limit.oval.xml
|
|
|
0b628f |
@@ -0,0 +1,38 @@
|
|
|
0b628f |
+
|
|
|
0b628f |
+<oval_definitions xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:ind="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ind-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" xmlns:unix-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix" xmlns:lin-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5" xsi:schemaLocation="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix unix-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5#independent independent-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5#linux linux-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5 oval-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 oval-common-schema.xsd">
|
|
|
0b628f |
+ <generator>
|
|
|
0b628f |
+ <oval:schema_version>5.11.1</oval:schema_version>
|
|
|
0b628f |
+ <oval:timestamp>0001-01-01T00:00:00+00:00</oval:timestamp>
|
|
|
0b628f |
+ </generator>
|
|
|
0b628f |
+
|
|
|
0b628f |
+ <definitions>
|
|
|
0b628f |
+ <definition class="compliance" version="1" id="oval:x:def:1">
|
|
|
0b628f |
+ <metadata>
|
|
|
0b628f |
+ <title>The regular expression and the provided file should exceed recursion limits within pcre_exec used in the probe and cause a segfault.</title>
|
|
|
0b628f |
+ <description>x</description>
|
|
|
0b628f |
+ <affected family="unix">
|
|
|
0b628f |
+ <platform>x</platform>
|
|
|
0b628f |
+ </affected>
|
|
|
0b628f |
+ </metadata>
|
|
|
0b628f |
+ <criteria>
|
|
|
0b628f |
+ <criterion test_ref="oval:x:tst:1" comment="always pass"/>
|
|
|
0b628f |
+ </criteria>
|
|
|
0b628f |
+ </definition>
|
|
|
0b628f |
+ </definitions>
|
|
|
0b628f |
+
|
|
|
0b628f |
+ <tests>
|
|
|
0b628f |
+ <ind:textfilecontent54_test id="oval:x:tst:1" version="1" comment="Match 3 audit rules" check="all">
|
|
|
0b628f |
+ <ind:object object_ref="oval:x:obj:1"/>
|
|
|
0b628f |
+ </ind:textfilecontent54_test>
|
|
|
0b628f |
+ </tests>
|
|
|
0b628f |
+
|
|
|
0b628f |
+ <objects>
|
|
|
0b628f |
+ <ind:textfilecontent54_object id="oval:x:obj:1" version="1" comment="Object representing file">
|
|
|
0b628f |
+ <ind:path>/tmp</ind:path>
|
|
|
0b628f |
+ <ind:filename>30-ospp-v42.rules</ind:filename>
|
|
|
0b628f |
+ <ind:pattern operation="pattern match">-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create(?:[^.]|\.\s)*-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification(?:[^.]|\.\s)*-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-access</ind:pattern>
|
|
|
0b628f |
+ <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
|
|
|
0b628f |
+ </ind:textfilecontent54_object>
|
|
|
0b628f |
+ </objects>
|
|
|
0b628f |
+
|
|
|
0b628f |
+</oval_definitions>
|
|
|
0b628f |
diff --git a/tests/probes/textfilecontent54/test_recursion_limit.sh b/tests/probes/textfilecontent54/test_recursion_limit.sh
|
|
|
0b628f |
new file mode 100755
|
|
|
0b628f |
index 000000000..2619dafdd
|
|
|
0b628f |
--- /dev/null
|
|
|
0b628f |
+++ b/tests/probes/textfilecontent54/test_recursion_limit.sh
|
|
|
0b628f |
@@ -0,0 +1,31 @@
|
|
|
0b628f |
+#!/usr/bin/env bash
|
|
|
0b628f |
+
|
|
|
0b628f |
+set -e -o pipefail
|
|
|
0b628f |
+
|
|
|
0b628f |
+. $builddir/tests/test_common.sh
|
|
|
0b628f |
+
|
|
|
0b628f |
+probecheck "textfilecontent54" || exit 255
|
|
|
0b628f |
+
|
|
|
0b628f |
+cp $srcdir/30-ospp-v42.rules /tmp
|
|
|
0b628f |
+
|
|
|
0b628f |
+name=$(basename $0 .sh)
|
|
|
0b628f |
+input=$srcdir/$name.oval.xml
|
|
|
0b628f |
+result=$(mktemp)
|
|
|
0b628f |
+stdout=$(mktemp)
|
|
|
0b628f |
+stderr=$(mktemp)
|
|
|
0b628f |
+
|
|
|
0b628f |
+$OSCAP oval eval --results $result $input > $stdout 2> $stderr
|
|
|
0b628f |
+
|
|
|
0b628f |
+grep -q "Function pcre_exec() failed to match a regular expression with return code -21" $stderr
|
|
|
0b628f |
+
|
|
|
0b628f |
+assert_exists 1 '/oval_results/results/system/definitions/definition[@definition_id="oval:x:def:1" and @result="error"]'
|
|
|
0b628f |
+
|
|
|
0b628f |
+co='/oval_results/results/system/oval_system_characteristics/collected_objects'
|
|
|
0b628f |
+assert_exists 1 $co'/object[@flag="error"]'
|
|
|
0b628f |
+assert_exists 1 $co'/object/message[@level="error"]'
|
|
|
0b628f |
+assert_exists 1 $co'/object/message[text()="Regular expression pattern match failed in file /tmp/30-ospp-v42.rules with error -21."]'
|
|
|
0b628f |
+
|
|
|
0b628f |
+rm -f /tmp/30-ospp-v42.rules
|
|
|
0b628f |
+rm -f $result
|
|
|
0b628f |
+rm -f $stdout
|
|
|
0b628f |
+rm -f $stderr
|