Skip to content

Commit 826eeb7

Browse files
authored
Merge pull request #2051 from jan-cerny/items_limit
Introduce a limit of collected items
2 parents a8507e2 + 6b29c04 commit 826eeb7

14 files changed

+119
-27
lines changed

docs/manual/manual.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,7 @@ not considered local by the scanner:
16181618
* `SEXP_VALIDATE_DISABLE` - If set, `oscap` will not validate SEXP expressions during its execution.
16191619
* `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.
16201620
* `OSCAP_PROBE_MEMORY_USAGE_RATIO` - maximum memory usage ratio (used/total) for OpenSCAP probes, default: 0.1
1621+
* `OSCAP_PROBE_MAX_COLLECTED_ITEMS` - maximal count of collected items by OpenSCAP probe for a single OVAL object evaluation
16211622

16221623
Also, OpenSCAP uses `libcurl` library which also can be configured using environment variables. See https://curl.se/libcurl/c/libcurl-env.html[the list of libcurl environment variables].
16231624

src/OVAL/probes/independent/textfilecontent54_probe.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,14 @@ static int process_file(const char *prefix, const char *path, const char *file,
240240
item = create_item(path, file, pfd->pattern,
241241
cur_inst, substrs, substr_cnt, over);
242242

243-
probe_item_collect(pfd->ctx, item);
244-
245243
for (k = 0; k < substr_cnt; ++k)
246244
free(substrs[k]);
247245
free(substrs);
246+
int pic_ret = probe_item_collect(pfd->ctx, item);
247+
if (pic_ret == 2 || pic_ret == -1) {
248+
ret = -4;
249+
break;
250+
}
248251
}
249252
}
250253
} while (substr_cnt > 0 && ofs < buf_used);

src/OVAL/probes/probe/icache.c

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "probe-api.h"
4040
#include "common/debug_priv.h"
4141
#include "common/memusage.h"
42+
#include "oscap_helpers.h"
4243

4344
#include "probe.h"
4445
#include "icache.h"
@@ -528,6 +529,30 @@ static int probe_cobj_memcheck(size_t item_cnt, double max_ratio)
528529
return (0);
529530
}
530531

532+
static int _mark_collected_object_as_incomplete(struct probe_ctx *ctx, const char *message)
533+
{
534+
/*
535+
* Don't set the message again if the collected object is
536+
* already flagged as incomplete.
537+
*/
538+
if (probe_cobj_get_flag(ctx->probe_out) == SYSCHAR_FLAG_INCOMPLETE) {
539+
return 0;
540+
}
541+
/*
542+
* Sync with the icache thread before modifying the
543+
* collected object.
544+
*/
545+
if (probe_icache_nop(ctx->icache) != 0) {
546+
return -1;
547+
}
548+
549+
SEXP_t *sexp_msg = probe_msg_creat(OVAL_MESSAGE_LEVEL_WARNING, (char *) message);
550+
probe_cobj_add_msg(ctx->probe_out, sexp_msg);
551+
probe_cobj_set_flag(ctx->probe_out, SYSCHAR_FLAG_INCOMPLETE);
552+
SEXP_free(sexp_msg);
553+
return 0;
554+
}
555+
531556
/**
532557
* Collect an item
533558
* This function adds an item the collected object assosiated
@@ -557,6 +582,16 @@ int probe_item_collect(struct probe_ctx *ctx, SEXP_t *item)
557582
cobj_itemcnt = SEXP_list_length(cobj_content);
558583
SEXP_free(cobj_content);
559584

585+
if (ctx->max_collected_items != OSCAP_PROBE_COLLECT_UNLIMITED && cobj_itemcnt >= ctx->max_collected_items) {
586+
char *message = oscap_sprintf("Object is incomplete because the object matches more than %ld items.", ctx->max_collected_items);
587+
if (_mark_collected_object_as_incomplete(ctx, message) != 0) {
588+
free(message);
589+
return -1;
590+
}
591+
free(message);
592+
return 2;
593+
}
594+
560595
memcheck_ret = probe_cobj_memcheck(cobj_itemcnt, ctx->max_mem_ratio);
561596
if (memcheck_ret == -1) {
562597
dE("Failed to check available memory");
@@ -565,27 +600,9 @@ int probe_item_collect(struct probe_ctx *ctx, SEXP_t *item)
565600
}
566601
if (memcheck_ret == 1) {
567602
SEXP_free(item);
568-
569-
/*
570-
* Don't set the message again if the collected object is
571-
* already flagged as incomplete.
572-
*/
573-
if (probe_cobj_get_flag(ctx->probe_out) != SYSCHAR_FLAG_INCOMPLETE) {
574-
SEXP_t *msg;
575-
/*
576-
* Sync with the icache thread before modifying the
577-
* collected object.
578-
*/
579-
if (probe_icache_nop(ctx->icache) != 0)
580-
return -1;
581-
582-
msg = probe_msg_creat(OVAL_MESSAGE_LEVEL_WARNING,
583-
"Object is incomplete due to memory constraints.");
584-
585-
probe_cobj_add_msg(ctx->probe_out, msg);
586-
probe_cobj_set_flag(ctx->probe_out, SYSCHAR_FLAG_INCOMPLETE);
587-
588-
SEXP_free(msg);
603+
const char *message = "Object is incomplete due to memory constraints.";
604+
if (_mark_collected_object_as_incomplete(ctx, message) != 0) {
605+
return -1;
589606
}
590607

591608
return 2;

src/OVAL/probes/probe/probe.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@
4343
#include "common/util.h"
4444
#include "common/compat_pthread_barrier.h"
4545

46+
/* default max. memory usage ratio - used/total */
47+
/* can be overridden by environment variable OSCAP_PROBE_MEMORY_USAGE_RATIO */
48+
#define OSCAP_PROBE_MEMORY_USAGE_RATIO_DEFAULT 0.33
49+
50+
/* By default, probes can collect unlimited amount of items. Ths behavior can
51+
* be overridden by environment variable OSCAP_PROBE_MAX_COLLECTED_ITEMS.
52+
*/
53+
#define OSCAP_PROBE_COLLECT_UNLIMITED 0
54+
4655
typedef struct {
4756
pthread_rwlock_t rwlock;
4857
uint32_t flags;
@@ -84,6 +93,7 @@ struct probe_ctx {
8493
probe_icache_t *icache; /**< item cache */
8594
int offline_mode;
8695
double max_mem_ratio;
96+
size_t max_collected_items;
8797
};
8898

8999
typedef enum {

src/OVAL/probes/probe/worker.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ extern int chroot(const char *);
5252
#include "probe-table.h"
5353
#include "probe.h"
5454

55-
/* default max. memory usage ratio - used/total */
56-
/* can be overridden by environment variable OSCAP_PROBE_MEMORY_USAGE_RATIO */
57-
#define OSCAP_PROBE_MEMORY_USAGE_RATIO_DEFAULT 0.33
58-
5955
extern bool OSCAP_GSYM(varref_handling);
6056
extern void *OSCAP_GSYM(probe_arg);
6157

@@ -1078,6 +1074,14 @@ SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
10781074
if (max_ratio > 0)
10791075
pctx.max_mem_ratio = max_ratio;
10801076
}
1077+
pctx.max_collected_items = OSCAP_PROBE_COLLECT_UNLIMITED;
1078+
char *max_collected_items_str = getenv("OSCAP_PROBE_MAX_COLLECTED_ITEMS");
1079+
if (max_collected_items_str != NULL) {
1080+
int max_collected_items = strtol(max_collected_items_str, NULL, 0);
1081+
if (max_collected_items > 0) {
1082+
pctx.max_collected_items = max_collected_items;
1083+
}
1084+
}
10811085

10821086
/* simple object */
10831087
pctx.icache = probe->icache;

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ add_subdirectory("mitre")
3333
add_subdirectory("nist")
3434
add_subdirectory("oscap_string")
3535
add_subdirectory("oval_details")
36+
add_subdirectory("probe_behavior")
3637
add_subdirectory("probes")
3738
add_subdirectory("report")
3839
add_subdirectory("sce")

tests/probe_behavior/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_oscap_test("collect_limit.sh")
File renamed without changes.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0"?>
2+
<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">
3+
<generator>
4+
<oval:schema_version>5.10.1</oval:schema_version>
5+
<oval:timestamp>0001-01-01T00:00:00+00:00</oval:timestamp>
6+
</generator>
7+
8+
<definitions>
9+
<definition class="compliance" version="1" id="oval:x:def:1">
10+
<metadata>
11+
<title>x</title>
12+
<description>x</description>
13+
<affected family="unix">
14+
<platform>x</platform>
15+
</affected>
16+
</metadata>
17+
<criteria>
18+
<criterion test_ref="oval:x:tst:1" comment="always pass"/>
19+
</criteria>
20+
</definition>
21+
</definitions>
22+
23+
<tests>
24+
<ind:textfilecontent54_test id="oval:x:tst:1" version="1" comment="Test" check="all">
25+
<ind:object object_ref="oval:x:obj:1"/>
26+
</ind:textfilecontent54_test>
27+
</tests>
28+
29+
<objects>
30+
<ind:textfilecontent54_object id="oval:x:obj:1" version="1" comment="The object matches each line in /tmp/longfile.">
31+
<ind:filepath>/tmp/longfile</ind:filepath>
32+
<ind:pattern operation="pattern match">^.*$</ind:pattern>
33+
<ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
34+
</ind:textfilecontent54_object>
35+
</objects>
36+
37+
</oval_definitions>

tests/probe_behavior/collect_limit.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
set -e -o pipefail
4+
5+
. $builddir/tests/test_common.sh
6+
7+
export OSCAP_PROBE_MAX_COLLECTED_ITEMS=100
8+
seq 110 > /tmp/longfile
9+
result=$(mktemp)
10+
$OSCAP oval eval --results "$result" $srcdir/collect_limit.oval.xml
11+
assert_exists 1 '/oval_results/results/system/oval_system_characteristics/collected_objects/object'
12+
assert_exists 1 '/oval_results/results/system/oval_system_characteristics/collected_objects/object[@flag="incomplete"]'
13+
assert_exists 1 '/oval_results/results/system/oval_system_characteristics/collected_objects/object/message[@level="warning"]'
14+
text="Object is incomplete because the object matches more than 100 items."
15+
assert_exists 1 "/oval_results/results/system/oval_system_characteristics/collected_objects/object/message[text()=\"$text\"]"
16+
assert_exists 100 '/oval_results/results/system/oval_system_characteristics/system_data/ind-sys:textfilecontent_item'
17+
rm -f /tmp/longfile
18+
rm -f "$result"

0 commit comments

Comments
 (0)