Skip to content

Commit

Permalink
Merge pull request OpenSCAP#2052 from jan-cerny/block_paths
Browse files Browse the repository at this point in the history
Skip certain paths from scanning
  • Loading branch information
evgenyz authored Jan 16, 2024
2 parents 3222734 + 2d20f33 commit 9b38fc2
Show file tree
Hide file tree
Showing 24 changed files with 410 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/manual/manual.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1647,6 +1647,7 @@ not considered local by the scanner:
* `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.
* `OSCAP_PROBE_MEMORY_USAGE_RATIO` - maximum memory usage ratio (used/total) for OpenSCAP probes, default: 0.1
* `OSCAP_PROBE_MAX_COLLECTED_ITEMS` - maximal count of collected items by OpenSCAP probe for a single OVAL object evaluation
* `OSCAP_PROBE_IGNORE_PATHS` - Skip given paths during evaluation. If multiple paths should be skipped they need to be separated by a colon. The paths should be absolute canonical paths.

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].

Expand Down
4 changes: 4 additions & 0 deletions src/OVAL/probes/independent/filehash58_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ static int filehash58_cb(const char *prefix, const char *p, const char *f, const
memcpy (pbuf + plen, f, sizeof (char) * flen);
pbuf[plen+flen] = '\0';

if (probe_path_is_blocked(pbuf, ctx->blocked_paths)) {
return 0;
}

/*
* Open the file
*/
Expand Down
4 changes: 4 additions & 0 deletions src/OVAL/probes/independent/filehash_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ static int filehash_cb (const char *prefix, const char *p, const char *f, probe_
pbuf[plen+flen] = '\0';
include_filepath = oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.6)) >= 0;

if (probe_path_is_blocked(pbuf, ctx->blocked_paths)) {
return 0;
}

/*
* Open the file
*/
Expand Down
10 changes: 7 additions & 3 deletions src/OVAL/probes/independent/textfilecontent54_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
#include "common/debug_priv.h"
#include "common/util.h"
#include "common/oscap_pcre.h"
#include "common/list.h"

#include "textfilecontent54_probe.h"

#define FILE_SEPARATOR '/'
Expand Down Expand Up @@ -118,9 +120,8 @@ struct pfdata {
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)
static int process_file(const char *prefix, const char *path, const char *file, struct pfdata *pfd, oval_schema_version_t over, struct oscap_list *blocked_paths)
{
struct pfdata *pfd = (struct pfdata *) arg;
int ret = 0, path_len, file_len, cur_inst = 0, fd = -1, substr_cnt,
buf_size = 0, buf_used = 0, ofs = 0, buf_inc = 4096;
char **substrs = NULL;
Expand All @@ -144,6 +145,9 @@ static int process_file(const char *prefix, const char *path, const char *file,

memcpy(whole_path + path_len, file, file_len + 1);

if (probe_path_is_blocked(whole_path, blocked_paths)) {
goto cleanup;
}
/*
* If stat() fails, don't report an error and just skip the file.
* This is an expected situation, because the fts_*() functions
Expand Down Expand Up @@ -361,7 +365,7 @@ int textfilecontent54_probe_main(probe_ctx *ctx, void *arg)
if (ofts_ent->fts_info == FTS_F
|| ofts_ent->fts_info == FTS_SL) {
// todo: handle return code
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd, over);
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd, over, ctx->blocked_paths);
}
oval_ftsent_free(ofts_ent);
}
Expand Down
8 changes: 6 additions & 2 deletions src/OVAL/probes/independent/textfilecontent_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ struct pfdata {
probe_ctx *ctx;
};

static int process_file(const char *prefix, const char *path, const char *filename, void *arg, oval_schema_version_t over)
static int process_file(const char *prefix, const char *path, const char *filename, void *arg, oval_schema_version_t over, struct oscap_list *blocked_paths)
{
struct pfdata *pfd = (struct pfdata *) arg;
int ret = 0, path_len, filename_len;
Expand Down Expand Up @@ -170,6 +170,10 @@ static int process_file(const char *prefix, const char *path, const char *filena
}
memcpy(whole_path + path_len, filename, filename_len + 1);

if (probe_path_is_blocked(whole_path, blocked_paths)) {
goto cleanup;
}

/*
* If stat() fails, don't report an error and just skip the file.
* This is an expected situation, because the fts_*() functions
Expand Down Expand Up @@ -294,7 +298,7 @@ int textfilecontent_probe_main(probe_ctx *ctx, void *arg)
if (ofts_ent->fts_info == FTS_F
|| ofts_ent->fts_info == FTS_SL) {
// todo: handle return code
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd, over);
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd, over, ctx->blocked_paths);
}
oval_ftsent_free(ofts_ent);
}
Expand Down
9 changes: 6 additions & 3 deletions src/OVAL/probes/independent/xmlfilecontent_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ static xmlDocPtr strip_ns(xmlDocPtr doc)
return result;
}

static int process_file(const char *prefix, const char *path, const char *filename, void *arg)
static int process_file(const char *prefix, const char *path, const char *filename, struct pfdata *pfd, struct oscap_list *blocked_paths)
{
struct pfdata *pfd = (struct pfdata *) arg;
int ret = 0, path_len, filename_len;
char *whole_path = NULL;
xmlDoc *doc = NULL;
Expand All @@ -171,6 +170,10 @@ static int process_file(const char *prefix, const char *path, const char *filena

memcpy(whole_path + path_len, filename, filename_len + 1);

if (probe_path_is_blocked(whole_path, blocked_paths)) {
goto cleanup;
}

if (prefix == NULL) {
doc = xmlParseFile(whole_path);
} else {
Expand Down Expand Up @@ -393,7 +396,7 @@ int xmlfilecontent_probe_main(probe_ctx *ctx, void *arg)

if ((ofts = oval_fts_open_prefixed(prefix, path_ent, filename_ent, filepath_ent, behaviors_ent, probe_ctx_getresult(ctx))) != NULL) {
while ((ofts_ent = oval_fts_read(ofts)) != NULL) {
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd);
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd, ctx->blocked_paths);
oval_ftsent_free(ofts_ent);
}

Expand Down
3 changes: 3 additions & 0 deletions src/OVAL/probes/independent/yamlfilecontent_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ static int process_yaml_file(const char *prefix, const char *path, const char *f
yaml_parser_initialize(&parser);

char *filepath = oscap_path_join(path, filename);
if (probe_path_is_blocked(filepath, ctx->blocked_paths)) {
goto cleanup;
}
char *filepath_with_prefix = oscap_path_join(prefix, filepath);

FILE *yaml_file = fopen(filepath_with_prefix, "r");
Expand Down
16 changes: 16 additions & 0 deletions src/OVAL/probes/probe-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1794,4 +1794,20 @@ SEXP_t *probe_obj_getmask(SEXP_t *obj)
SEXP_free(objents);
return (mask);
}

bool probe_path_is_blocked(const char *path, struct oscap_list *blocked_paths)
{
bool res = false;
struct oscap_iterator *it = oscap_iterator_new(blocked_paths);
while (oscap_iterator_has_more(it)) {
const char *item = oscap_iterator_next(it);
if (oscap_path_startswith(path, item)) {
res = true;
break;
}
}
oscap_iterator_free(it);
return res;
}

/// @}
1 change: 1 addition & 0 deletions src/OVAL/probes/probe/probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct probe_ctx {
int offline_mode;
double max_mem_ratio;
size_t max_collected_items;
struct oscap_list *blocked_paths;
};

typedef enum {
Expand Down
22 changes: 22 additions & 0 deletions src/OVAL/probes/probe/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,23 @@ static SEXP_t *probe_set_eval(probe_t *probe, SEXP_t *set, size_t depth)
return result;
}

static void _add_blocked_paths(struct oscap_list *bpaths)
{
char *envar = getenv("OSCAP_PROBE_IGNORE_PATHS");
if (envar == NULL) {
return;
}
#ifdef OS_WINDOWS
dW("OSCAP_PROBE_IGNORE_PATHS isn't effective on Windows.");
#else
char **paths = oscap_split(envar, ":");
for (int i = 0; paths[i]; ++i) {
oscap_list_add(bpaths, strdup(paths[i]));
}
free(paths);
#endif
}

/**
* Worker thread function. This functions handles the evalution of objects and sets.
* @param msg_in SEAP message with the request which contains the object to be evaluated
Expand Down Expand Up @@ -1083,6 +1100,9 @@ SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
}
}

pctx.blocked_paths = oscap_list_new();
_add_blocked_paths(pctx.blocked_paths);

/* simple object */
pctx.icache = probe->icache;
pctx.filters = probe_prepare_filters(probe, probe_in);
Expand Down Expand Up @@ -1142,6 +1162,7 @@ SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
SEXP_free(pctx.filters);
SEXP_free(probe_in);
SEXP_free(mask);
oscap_list_free(pctx.blocked_paths, free);
*ret = PROBE_EUNKNOWN;
return (NULL);
}
Expand Down Expand Up @@ -1181,6 +1202,7 @@ SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
}

SEXP_free(pctx.filters);
oscap_list_free(pctx.blocked_paths, free);
}

SEXP_free(probe_in);
Expand Down
8 changes: 8 additions & 0 deletions src/OVAL/probes/public/probe-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include <oval_types.h>
#include "sexp-types.h"
#include "oscap_export.h"
#include "list.h"

/*
* items
Expand Down Expand Up @@ -538,4 +539,11 @@ OSCAP_API oval_schema_version_t probe_obj_get_platform_schema_version(const SEXP
*/
OSCAP_API SEXP_t *probe_obj_getmask(SEXP_t *obj);

/**
* Check if the given path matches any of the paths in the blocked paths list
* @param path path to be examined
* @param blocked_paths list of blocked paths
*/
OSCAP_API bool probe_path_is_blocked(const char *path, struct oscap_list *blocked_paths);

/// @}
8 changes: 6 additions & 2 deletions src/OVAL/probes/unix/file_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ static SEXP_t *has_extended_acl(const char *path)
#endif
}

static int file_cb(const char *prefix, const char *p, const char *f, void *ptr, oval_schema_version_t over, struct ID_cache *cache, struct gr_sexps *grs, SEXP_t *gr_lastpath)
static int file_cb(const char *prefix, const char *p, const char *f, void *ptr, oval_schema_version_t over, struct ID_cache *cache, struct gr_sexps *grs, SEXP_t *gr_lastpath, struct oscap_list *blocked_paths)
{
char path_buffer[PATH_MAX];
SEXP_t *item;
Expand All @@ -325,6 +325,10 @@ static int file_cb(const char *prefix, const char *p, const char *f, void *ptr,
st_path = path_buffer;
}

if (probe_path_is_blocked(st_path, blocked_paths)) {
return 0;
}

char *st_path_with_prefix = oscap_path_join(prefix, st_path);
if (lstat(st_path_with_prefix, &st) == -1) {
dD("lstat failed when processing %s: errno=%u, %s.", st_path, errno, strerror (errno));
Expand Down Expand Up @@ -509,7 +513,7 @@ int file_probe_main(probe_ctx *ctx, void *mutex)

if ((ofts = oval_fts_open_prefixed(prefix, path, filename, filepath, behaviors, probe_ctx_getresult(ctx))) != NULL) {
while ((ofts_ent = oval_fts_read(ofts)) != NULL) {
if (file_cb(prefix, ofts_ent->path, ofts_ent->file, &cbargs, over, cache, grs, &gr_lastpath) != 0) {
if (file_cb(prefix, ofts_ent->path, ofts_ent->file, &cbargs, over, cache, grs, &gr_lastpath, ctx->blocked_paths) != 0) {
oval_ftsent_free(ofts_ent);
break;
}
Expand Down
14 changes: 11 additions & 3 deletions src/OVAL/probes/unix/fileextendedattribute_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct cbargs {
};

#if defined(OS_FREEBSD)
static int file_cb(const char *prefix, const char *p, const char *f, void *ptr, SEXP_t *gr_lastpath)
static int file_cb(const char *prefix, const char *p, const char *f, void *ptr, SEXP_t *gr_lastpath, struct oscap_list *blocked_paths)
{
char path_buffer[PATH_MAX];
SEXP_t *item;
Expand Down Expand Up @@ -110,6 +110,10 @@ static int file_cb(const char *prefix, const char *p, const char *f, void *ptr,
st_path = path_buffer;
}

if (probe_path_is_blocked(st_path, blocked_paths)) {
return 0;
}

char *st_path_with_prefix = oscap_path_join(prefix, st_path);

/* update lastpath if needed */
Expand Down Expand Up @@ -205,7 +209,7 @@ static int file_cb(const char *prefix, const char *p, const char *f, void *ptr,
}

#else
static int file_cb(const char *prefix, const char *p, const char *f, void *ptr, SEXP_t *gr_lastpath)
static int file_cb(const char *prefix, const char *p, const char *f, void *ptr, SEXP_t *gr_lastpath, struct oscap_list *blocked_paths)
{
char path_buffer[PATH_MAX];
SEXP_t *item, xattr_name;
Expand All @@ -231,6 +235,10 @@ static int file_cb(const char *prefix, const char *p, const char *f, void *ptr,

SEXP_init(&xattr_name);

if (probe_path_is_blocked(st_path, blocked_paths)) {
return 0;
}

char *st_path_with_prefix = oscap_path_join(prefix, st_path);
do {
/* estimate the size of the buffer */
Expand Down Expand Up @@ -441,7 +449,7 @@ int fileextendedattribute_probe_main(probe_ctx *ctx, void *mutex)

if ((ofts = oval_fts_open_prefixed(prefix, path, filename, filepath, behaviors, probe_ctx_getresult(ctx))) != NULL) {
while ((ofts_ent = oval_fts_read(ofts)) != NULL) {
file_cb(prefix, ofts_ent->path, ofts_ent->file, &cbargs, &gr_lastpath);
file_cb(prefix, ofts_ent->path, ofts_ent->file, &cbargs, &gr_lastpath, ctx->blocked_paths);
oval_ftsent_free(ofts_ent);
}
oval_fts_close(ofts);
Expand Down
4 changes: 4 additions & 0 deletions src/OVAL/probes/unix/symlink_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ static int collect_symlink(SEXP_t *ent, probe_ctx *ctx)
if (pathname == NULL) {
return PROBE_EINVAL;
}
if (probe_path_is_blocked(pathname, ctx->blocked_paths)) {
free(pathname);
return 0;
}

if (lstat(pathname, &sb) == -1) {
if (errno == ENOENT) {
Expand Down
32 changes: 32 additions & 0 deletions src/common/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,35 @@ int oscap_open_writable(const char *filename)
}
return fd;
}

bool oscap_path_startswith(const char *path, const char *prefix)
{
bool res = true;
const char *del = "/";
char *path_dup = oscap_strdup(path);
char **path_split = oscap_split(path_dup, del);
char *prefix_dup = oscap_strdup(prefix);
char **prefix_split = oscap_split(prefix_dup, del);
int i = 0, j = 0;
while (prefix_split[i] && path_split[j]) {
if (!strcmp(prefix_split[i], "")) {
++i;
continue;
}
if (!strcmp(path_split[j], "")) {
++j;
continue;
}
if (strcmp(prefix_split[i], path_split[j])) {
res = false;
break;
}
++i;
++j;
}
free(path_dup);
free(path_split);
free(prefix_dup);
free(prefix_split);
return res;
}
8 changes: 8 additions & 0 deletions src/common/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,4 +540,12 @@ char *oscap_windows_error_message(unsigned long error_code);
*/
int oscap_open_writable(const char *filename);

/**
* Check if a path starts with the given prefix
* @param path file system path
* @param prefix file system path that will be tested if it's a prefix of the path parameter
* @return true or false
*/
bool oscap_path_startswith(const char *path, const char *prefix);

#endif /* OSCAP_UTIL_H_ */
1 change: 1 addition & 0 deletions tests/API/OVAL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ add_oscap_test("test_api_oval.sh")
add_subdirectory("glob_to_regex")
add_subdirectory("report_variable_values")
add_subdirectory("schema_version")
add_subdirectory("skip_paths")
add_subdirectory("unittests")
add_subdirectory("validate")
2 changes: 2 additions & 0 deletions tests/API/OVAL/skip_paths/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_oscap_test("test_skip_paths.sh")
add_oscap_test("test_skip_paths_offline.sh")
3 changes: 3 additions & 0 deletions tests/API/OVAL/skip_paths/test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<parent>
<child>text</child>
</parent>
Loading

0 comments on commit 9b38fc2

Please sign in to comment.