Blame SOURCES/openscap-1.2.18-memory-limits-PR_1803.patch

8b65ee
From 85a13f1f8e8d1bdbd0d5b96f543c808a1548db51 Mon Sep 17 00:00:00 2001
8b65ee
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
8b65ee
Date: Mon, 30 Aug 2021 15:44:37 +0200
8b65ee
Subject: [PATCH 1/3] Lower memory limits and improve their checking
8b65ee
8b65ee
This patch attempts to mitigate problems caused by a large amount of
8b65ee
collected objects such as rhbz#1932833.
8b65ee
8b65ee
Specifically, these changes are made:
8b65ee
- Lower the threshold so that the amount of used memory is checked when
8b65ee
  only 1000 items are collected for the given OVAL object. That's
8b65ee
  because 32768 items (the original value) is already a large amount which
8b65ee
  occupies a lot of memory during further processing.
8b65ee
- Lower the memory usage ratio limit for the probe to 10 %. We have
8b65ee
  found experimentally that giving the probe 15 % or more will cause the
8b65ee
  oscap process to be killed when processing the collected data and
8b65ee
  generating results.
8b65ee
- In the calling function probe_item_collect, distinguish between return
8b65ee
  codes which means different behavior when there is insufficient memory
8b65ee
  than when the memory consumption can't be checked.
8b65ee
- Improve the warning message to show greater details about memory
8b65ee
  consumption to the user.
8b65ee
- Remove the check for the absolute amount of remaining free memory. As
8b65ee
  we can see on the example of rhbz#1932833, on systems with large
8b65ee
  amount of memory the remaining memory of 512 MB isn't enough memory for
8b65ee
  openscap to process the collected data. At the same time, if we lowered
8b65ee
  the usage ratio, we don't need this anymore.
8b65ee
- Remove useless message "spt:" from the verbose log because it's
8b65ee
  produced many times and pollutes the log extremely.
8b65ee
---
8b65ee
 src/OVAL/probes/probe/icache.c | 23 +++++++++++------------
8b65ee
 src/common/memusage.c          |  2 --
8b65ee
 2 files changed, 11 insertions(+), 14 deletions(-)
8b65ee
8b65ee
diff --git a/src/OVAL/probes/probe/icache.c b/src/OVAL/probes/probe/icache.c
8b65ee
index e67f5ebd3c..ccb7ee3057 100644
8b65ee
--- a/src/OVAL/probes/probe/icache.c
8b65ee
+++ b/src/OVAL/probes/probe/icache.c
8b65ee
@@ -457,9 +457,8 @@ int probe_icache_nop(probe_icache_t *cache)
8b65ee
         return (0);
8b65ee
 }
8b65ee
 
8b65ee
-#define PROBE_RESULT_MEMCHECK_CTRESHOLD  32768  /* item count */
8b65ee
-#define PROBE_RESULT_MEMCHECK_MINFREEMEM 512    /* MiB */
8b65ee
-#define PROBE_RESULT_MEMCHECK_MAXRATIO   0.8   /* max. memory usage ratio - used/total */
8b65ee
+#define PROBE_RESULT_MEMCHECK_CTRESHOLD  1000  /* item count */
8b65ee
+#define PROBE_RESULT_MEMCHECK_MAXRATIO   0.1   /* max. memory usage ratio - used/total */
8b65ee
 
8b65ee
 /**
8b65ee
  * Returns 0 if the memory constraints are not reached. Otherwise, 1 is returned.
8b65ee
@@ -481,18 +480,12 @@ static int probe_cobj_memcheck(size_t item_cnt)
8b65ee
 		c_ratio = (double)mu_proc.mu_rss/(double)(mu_sys.mu_total);
8b65ee
 
8b65ee
 		if (c_ratio > PROBE_RESULT_MEMCHECK_MAXRATIO) {
8b65ee
-			dW("Memory usage ratio limit reached! limit=%f, current=%f",
8b65ee
-			   PROBE_RESULT_MEMCHECK_MAXRATIO, c_ratio);
8b65ee
+			dW("Memory usage ratio limit reached! limit=%f, current=%f, used=%ld MB, free=%ld MB, total=%ld MB, count of items=%ld",
8b65ee
+			   PROBE_RESULT_MEMCHECK_MAXRATIO, c_ratio, mu_proc.mu_rss / 1024, mu_sys.mu_realfree / 1024, mu_sys.mu_total / 1024, item_cnt);
8b65ee
 			errno = ENOMEM;
8b65ee
 			return (1);
8b65ee
 		}
8b65ee
 
8b65ee
-		if ((mu_sys.mu_realfree / 1024) < PROBE_RESULT_MEMCHECK_MINFREEMEM) {
8b65ee
-			dW("Minimum free memory limit reached! limit=%zu, current=%zu",
8b65ee
-			   PROBE_RESULT_MEMCHECK_MINFREEMEM, mu_sys.mu_realfree / 1024);
8b65ee
-			errno = ENOMEM;
8b65ee
-			return (1);
8b65ee
-		}
8b65ee
 	}
8b65ee
 
8b65ee
 	return (0);
8b65ee
@@ -517,6 +510,7 @@ int probe_item_collect(struct probe_ctx *ctx, SEXP_t *item)
8b65ee
 {
8b65ee
 	SEXP_t *cobj_content;
8b65ee
 	size_t  cobj_itemcnt;
8b65ee
+	int memcheck_ret;
8b65ee
 
8b65ee
 	assume_d(ctx != NULL, -1);
8b65ee
 	assume_d(ctx->probe_out != NULL, -1);
8b65ee
@@ -526,7 +520,12 @@ int probe_item_collect(struct probe_ctx *ctx, SEXP_t *item)
8b65ee
 	cobj_itemcnt = SEXP_list_length(cobj_content);
8b65ee
 	SEXP_free(cobj_content);
8b65ee
 
8b65ee
-	if (probe_cobj_memcheck(cobj_itemcnt) != 0) {
8b65ee
+	memcheck_ret = probe_cobj_memcheck(cobj_itemcnt);
8b65ee
+	if (memcheck_ret == -1) {
8b65ee
+		dE("Failed to check available memory");
8b65ee
+		return -1;
8b65ee
+	}
8b65ee
+	if (memcheck_ret == 1) {
8b65ee
 
8b65ee
 		/*
8b65ee
 		 * Don't set the message again if the collected object is
8b65ee
diff --git a/src/common/memusage.c b/src/common/memusage.c
8b65ee
index af4ddb4d55..686ec9bc02 100644
8b65ee
--- a/src/common/memusage.c
8b65ee
+++ b/src/common/memusage.c
8b65ee
@@ -117,8 +117,6 @@ static int read_status(const char *source, void *base, struct stat_parser *spt,
8b65ee
 			sp = oscap_bfind(spt, spt_size, sizeof(struct stat_parser),
8b65ee
 			                 linebuf, (int(*)(void *, void *))&cmpkey);
8b65ee
 
8b65ee
-			dI("spt: %s", linebuf);
8b65ee
-
8b65ee
 			if (sp == NULL) {
8b65ee
 				/* drop end of unread line */
8b65ee
 				while (strchr(strval, '\n') == NULL) {
8b65ee
8b65ee
From bb26be6ffcf2a88c09e4f237516ad71db555158f Mon Sep 17 00:00:00 2001
8b65ee
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
8b65ee
Date: Tue, 7 Sep 2021 13:52:50 +0200
8b65ee
Subject: [PATCH 2/3] Allow to set memory ratio by environment variable
8b65ee
8b65ee
If the probe memory usage ratio limit will be too small or too big
8b65ee
in some situation, the user will be able to modify the limit easily
8b65ee
by setting the environment variable OSCAP_PROBE_MEMORY_USAGE_RATIO
8b65ee
to a different value. This can also help users when debugging memory
8b65ee
problems.
8b65ee
---
8b65ee
 docs/manual/manual.adoc        |  1 +
8b65ee
 src/OVAL/probes/probe/icache.c |  9 ++++-----
8b65ee
 src/OVAL/probes/probe/probe.h  |  1 +
8b65ee
 src/OVAL/probes/probe/worker.c | 12 ++++++++++++
8b65ee
 4 files changed, 18 insertions(+), 5 deletions(-)
8b65ee
8b65ee
diff --git a/docs/manual/manual.adoc b/docs/manual/manual.adoc
8b65ee
index 135426b6f0..b9ad60ced1 100644
8b65ee
--- a/docs/manual/manual.adoc
8b65ee
+++ b/docs/manual/manual.adoc
8b65ee
@@ -1925,6 +1925,7 @@ behaviour.
8b65ee
 
8b65ee
 * *OSCAP_FULL_VALIDATION=1* - validate all exported documents (slower)
8b65ee
 * *SEXP_VALIDATE_DISABLE=1* - do not validate SEXP expressions (faster)
8b65ee
+* *OSCAP_PROBE_MEMORY_USAGE_RATIO* - maximum memory usage ratio (used/total) for OpenSCAP probes, default: 0.1
8b65ee
 
8b65ee
 
8b65ee
 
8b65ee
diff --git a/src/OVAL/probes/probe/icache.c b/src/OVAL/probes/probe/icache.c
8b65ee
index ccb7ee3057..08a0c9ad07 100644
8b65ee
--- a/src/OVAL/probes/probe/icache.c
8b65ee
+++ b/src/OVAL/probes/probe/icache.c
8b65ee
@@ -458,13 +458,12 @@ int probe_icache_nop(probe_icache_t *cache)
8b65ee
 }
8b65ee
 
8b65ee
 #define PROBE_RESULT_MEMCHECK_CTRESHOLD  1000  /* item count */
8b65ee
-#define PROBE_RESULT_MEMCHECK_MAXRATIO   0.1   /* max. memory usage ratio - used/total */
8b65ee
 
8b65ee
 /**
8b65ee
  * Returns 0 if the memory constraints are not reached. Otherwise, 1 is returned.
8b65ee
  * In case of an error, -1 is returned.
8b65ee
  */
8b65ee
-static int probe_cobj_memcheck(size_t item_cnt)
8b65ee
+static int probe_cobj_memcheck(size_t item_cnt, double max_ratio)
8b65ee
 {
8b65ee
 	if (item_cnt > PROBE_RESULT_MEMCHECK_CTRESHOLD) {
8b65ee
 		struct proc_memusage mu_proc;
8b65ee
@@ -479,9 +478,9 @@ static int probe_cobj_memcheck(size_t item_cnt)
8b65ee
 
8b65ee
 		c_ratio = (double)mu_proc.mu_rss/(double)(mu_sys.mu_total);
8b65ee
 
8b65ee
-		if (c_ratio > PROBE_RESULT_MEMCHECK_MAXRATIO) {
8b65ee
+		if (c_ratio > max_ratio) {
8b65ee
 			dW("Memory usage ratio limit reached! limit=%f, current=%f, used=%ld MB, free=%ld MB, total=%ld MB, count of items=%ld",
8b65ee
-			   PROBE_RESULT_MEMCHECK_MAXRATIO, c_ratio, mu_proc.mu_rss / 1024, mu_sys.mu_realfree / 1024, mu_sys.mu_total / 1024, item_cnt);
8b65ee
+			max_ratio, c_ratio, mu_proc.mu_rss / 1024, mu_sys.mu_realfree / 1024, mu_sys.mu_total / 1024, item_cnt);
8b65ee
 			errno = ENOMEM;
8b65ee
 			return (1);
8b65ee
 		}
8b65ee
@@ -520,7 +519,7 @@ int probe_item_collect(struct probe_ctx *ctx, SEXP_t *item)
8b65ee
 	cobj_itemcnt = SEXP_list_length(cobj_content);
8b65ee
 	SEXP_free(cobj_content);
8b65ee
 
8b65ee
-	memcheck_ret = probe_cobj_memcheck(cobj_itemcnt);
8b65ee
+	memcheck_ret = probe_cobj_memcheck(cobj_itemcnt, ctx->max_mem_ratio);
8b65ee
 	if (memcheck_ret == -1) {
8b65ee
 		dE("Failed to check available memory");
8b65ee
 		return -1;
8b65ee
diff --git a/src/OVAL/probes/probe/probe.h b/src/OVAL/probes/probe/probe.h
8b65ee
index 0cfa234a2b..d98e741414 100644
8b65ee
--- a/src/OVAL/probes/probe/probe.h
8b65ee
+++ b/src/OVAL/probes/probe/probe.h
8b65ee
@@ -73,6 +73,7 @@ struct probe_ctx {
8b65ee
         SEXP_t         *filters;   /**< object filters (OVAL 5.8 and higher) */
8b65ee
         probe_icache_t *icache;    /**< item cache */
8b65ee
 	int offline_mode;
8b65ee
+	double max_mem_ratio;
8b65ee
 };
8b65ee
 
8b65ee
 typedef enum {
8b65ee
diff --git a/src/OVAL/probes/probe/worker.c b/src/OVAL/probes/probe/worker.c
8b65ee
index f89663544c..77f81e7885 100644
8b65ee
--- a/src/OVAL/probes/probe/worker.c
8b65ee
+++ b/src/OVAL/probes/probe/worker.c
8b65ee
@@ -37,6 +37,10 @@
8b65ee
 
8b65ee
 #include "worker.h"
8b65ee
 
8b65ee
+/* default max. memory usage ratio - used/total */
8b65ee
+/* can be overridden by environment variable OSCAP_PROBE_MEMORY_USAGE_RATIO */
8b65ee
+#define OSCAP_PROBE_MEMORY_USAGE_RATIO_DEFAULT 0.1
8b65ee
+
8b65ee
 extern bool  OSCAP_GSYM(varref_handling);
8b65ee
 extern void *OSCAP_GSYM(probe_arg);
8b65ee
 
8b65ee
@@ -924,6 +928,14 @@ SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
8b65ee
 
8b65ee
 		pctx.offline_mode = probe->selected_offline_mode;
8b65ee
 
8b65ee
+		pctx.max_mem_ratio = OSCAP_PROBE_MEMORY_USAGE_RATIO_DEFAULT;
8b65ee
+		char *max_ratio_str = getenv("OSCAP_PROBE_MEMORY_USAGE_RATIO");
8b65ee
+		if (max_ratio_str != NULL) {
8b65ee
+			double max_ratio = strtod(max_ratio_str, NULL);
8b65ee
+			if (max_ratio != 0)
8b65ee
+				pctx.max_mem_ratio = max_ratio;
8b65ee
+		}
8b65ee
+
8b65ee
 		/* simple object */
8b65ee
                 pctx.icache  = probe->icache;
8b65ee
 		pctx.filters = probe_prepare_filters(probe, probe_in);
8b65ee
8b65ee
From 521756ac0668e0c686798db957f8c06ef7d55085 Mon Sep 17 00:00:00 2001
8b65ee
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
8b65ee
Date: Wed, 15 Sep 2021 14:41:30 +0200
8b65ee
Subject: [PATCH 3/3] Update src/OVAL/probes/probe/worker.c
8b65ee
8b65ee
Co-authored-by: Evgeny Kolesnikov <evgenyz@gmail.com>
8b65ee
---
8b65ee
 src/OVAL/probes/probe/worker.c | 2 +-
8b65ee
 1 file changed, 1 insertion(+), 1 deletion(-)
8b65ee
8b65ee
diff --git a/src/OVAL/probes/probe/worker.c b/src/OVAL/probes/probe/worker.c
8b65ee
index 77f81e7885..9b920edc15 100644
8b65ee
--- a/src/OVAL/probes/probe/worker.c
8b65ee
+++ b/src/OVAL/probes/probe/worker.c
8b65ee
@@ -932,7 +932,7 @@ SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
8b65ee
 		char *max_ratio_str = getenv("OSCAP_PROBE_MEMORY_USAGE_RATIO");
8b65ee
 		if (max_ratio_str != NULL) {
8b65ee
 			double max_ratio = strtod(max_ratio_str, NULL);
8b65ee
-			if (max_ratio != 0)
8b65ee
+			if (max_ratio > 0)
8b65ee
 				pctx.max_mem_ratio = max_ratio;
8b65ee
 		}
8b65ee