Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skip certain paths from scanning #2052

Merged
merged 21 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/manual/manual.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,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)
evgenyz marked this conversation as resolved.
Show resolved Hide resolved
{
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")
evgenyz marked this conversation as resolved.
Show resolved Hide resolved
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
Loading