Skip to content

Commit

Permalink
Change textfilecontent(54) probes to not use chroot
Browse files Browse the repository at this point in the history
Adds a new parameter, 'prefix' to process file and to oval_fts_open.
This prefix is added to the FTS paths, and then removed from FTS paths,
and the added to lstat(), and open() calls. The prefix should not appear
in the OVAL results document, so that the user will feel like it has
chroot()ed. But chroot() is not used at all in these probes anymore.
  • Loading branch information
jan-cerny committed Mar 28, 2018
1 parent fae13c4 commit f02d86d
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 33 deletions.
30 changes: 17 additions & 13 deletions src/OVAL/probes/independent/textfilecontent.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,13 @@ static SEXP_t *create_item(const char *path, const char *filename, char *pattern
if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.6)) < 0) {
se_filepath = NULL;
} else {
se_filepath = SEXP_string_newf("%s%c%s", path, FILE_SEPARATOR, filename);
const size_t path_len = strlen(path);
/* Avoid 2 slashes */
if (path_len >= 1 && path[path_len - 1] == FILE_SEPARATOR) {
se_filepath = SEXP_string_newf("%s%s", path, filename);
} else {
se_filepath = SEXP_string_newf("%s%c%s", path, FILE_SEPARATOR, filename);
}
}

item = probe_item_create(OVAL_INDEPENDENT_TEXT_FILE_CONTENT, NULL,
Expand All @@ -229,11 +235,11 @@ struct pfdata {
probe_ctx *ctx;
};

static int process_file(const char *path, const char *filename, void *arg)
static int process_file(const char *prefix, const char *path, const char *filename, void *arg)
{
struct pfdata *pfd = (struct pfdata *) arg;
int ret = 0, path_len, filename_len;
char *whole_path = NULL;
char *whole_path = NULL, *whole_path_with_prefix = NULL;
FILE *fp = NULL;
struct stat st;

Expand Down Expand Up @@ -277,12 +283,13 @@ static int process_file(const char *path, const char *filename, void *arg)
* to return 'FTS_SL' and the presence of a valid target has to
* be determined with stat().
*/
if (stat(whole_path, &st) == -1)
whole_path_with_prefix = oscap_sprintf("%s%s", prefix ? prefix : "", whole_path);
if (stat(whole_path_with_prefix, &st) == -1)
goto cleanup;
if (!S_ISREG(st.st_mode))
goto cleanup;

fp = fopen(whole_path, "rb");
fp = fopen(whole_path_with_prefix, "rb");
if (fp == NULL) {
ret = -2;
goto cleanup;
Expand Down Expand Up @@ -323,6 +330,7 @@ static int process_file(const char *path, const char *filename, void *arg)
#elif defined USE_REGEX_POSIX
regfree(re);
#endif
free(whole_path_with_prefix);

return ret;
}
Expand All @@ -332,12 +340,6 @@ int probe_offline_mode_supported()
return PROBE_OFFLINE_OWN;
}

void *probe_init(void)
{
probe_setoption(PROBEOPT_OFFLINE_MODE_SUPPORTED, PROBE_OFFLINE_CHROOT);
return NULL;
}

int probe_main(probe_ctx *ctx, void *arg)
{
SEXP_t *path_ent, *filename_ent, *line_ent, *behaviors_ent, *filepath_ent, *probe_in;
Expand Down Expand Up @@ -388,12 +390,14 @@ int probe_main(probe_ctx *ctx, void *arg)
pfd.filename_ent = filename_ent;
pfd.ctx = ctx;

if ((ofts = oval_fts_open(NULL, path_ent, filename_ent, filepath_ent, behaviors_ent, probe_ctx_getresult(ctx))) != NULL) {
const char *prefix = getenv("OSCAP_PROBE_ROOT");

if ((ofts = oval_fts_open(prefix, path_ent, filename_ent, filepath_ent, behaviors_ent, probe_ctx_getresult(ctx))) != NULL) {
while ((ofts_ent = oval_fts_read(ofts)) != NULL) {
if (ofts_ent->fts_info == FTS_F
|| ofts_ent->fts_info == FTS_SL) {
// todo: handle return code
process_file(ofts_ent->path, ofts_ent->file, &pfd);
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd);
}
oval_ftsent_free(ofts_ent);
}
Expand Down
30 changes: 17 additions & 13 deletions src/OVAL/probes/independent/textfilecontent54.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,13 @@ static SEXP_t *create_item(const char *path, const char *filename, char *pattern
if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.6)) < 0) {
se_filepath = NULL;
} else {
se_filepath = SEXP_string_newf("%s%c%s", path, FILE_SEPARATOR, filename);
const size_t path_len = strlen(path);
/* Avoid 2 slashes */
if (path_len >= 1 && path[path_len - 1] == FILE_SEPARATOR) {
se_filepath = SEXP_string_newf("%s%s", path, filename);
} else {
se_filepath = SEXP_string_newf("%s%c%s", path, FILE_SEPARATOR, filename);
}
}

item = probe_item_create(OVAL_INDEPENDENT_TEXT_FILE_CONTENT, NULL,
Expand Down Expand Up @@ -220,12 +226,12 @@ struct pfdata {
#endif
};

static int process_file(const char *path, const char *file, void *arg)
static int process_file(const char *prefix, const char *path, const char *file, void *arg)
{
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 *whole_path = NULL, *buf = NULL;
char *whole_path = NULL, *whole_path_with_prefix = NULL, *buf = NULL;
SEXP_t *next_inst = NULL;
struct stat st;

Expand Down Expand Up @@ -254,12 +260,13 @@ static int process_file(const char *path, const char *file, void *arg)
* to return 'FTS_SL' and the presence of a valid target has to
* be determined with stat().
*/
if (stat(whole_path, &st) == -1)
whole_path_with_prefix = oscap_sprintf("%s%s", prefix ? prefix : "", whole_path);
if (stat(whole_path_with_prefix, &st) == -1)
goto cleanup;
if (!S_ISREG(st.st_mode))
goto cleanup;

fd = open(whole_path, O_RDONLY);
fd = open(whole_path_with_prefix, O_RDONLY);
if (fd == -1) {
SEXP_t *msg;

Expand Down Expand Up @@ -343,6 +350,7 @@ static int process_file(const char *path, const char *file, void *arg)
free(buf);
if (whole_path != NULL)
free(whole_path);
free(whole_path_with_prefix);

return ret;
}
Expand All @@ -352,12 +360,6 @@ int probe_offline_mode_supported()
return PROBE_OFFLINE_OWN;
}

void *probe_init(void)
{
probe_setoption(PROBEOPT_OFFLINE_MODE_SUPPORTED, PROBE_OFFLINE_CHROOT);
return NULL;
}

int probe_main(probe_ctx *ctx, void *arg)
{
SEXP_t *path_ent, *file_ent, *inst_ent, *bh_ent, *patt_ent, *filepath_ent, *probe_in;
Expand Down Expand Up @@ -503,12 +505,14 @@ int probe_main(probe_ctx *ctx, void *arg)
goto cleanup;
}
#endif
if ((ofts = oval_fts_open(NULL, path_ent, file_ent, filepath_ent, bh_ent, probe_ctx_getresult(ctx))) != NULL) {
const char *prefix = getenv("OSCAP_PROBE_ROOT");

if ((ofts = oval_fts_open(prefix, path_ent, file_ent, filepath_ent, bh_ent, probe_ctx_getresult(ctx))) != NULL) {
while ((ofts_ent = oval_fts_read(ofts)) != NULL) {
if (ofts_ent->fts_info == FTS_F
|| ofts_ent->fts_info == FTS_SL) {
// todo: handle return code
process_file(ofts_ent->path, ofts_ent->file, &pfd);
process_file(prefix, ofts_ent->path, ofts_ent->file, &pfd);
}
oval_ftsent_free(ofts_ent);
}
Expand Down
35 changes: 28 additions & 7 deletions src/OVAL/probes/oval_fts.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,28 @@ static OVAL_FTSENT *OVAL_FTSENT_new(OVAL_FTS *ofts, FTSENT *fts_ent)
ofts_ent = oscap_talloc(OVAL_FTSENT);

ofts_ent->fts_info = fts_ent->fts_info;
const size_t shift = ofts->prefix ? strlen(ofts->prefix) : 0;
if (ofts->ofts_sfilename || ofts->ofts_sfilepath) {
ofts_ent->path_len = pathlen_from_ftse(fts_ent->fts_pathlen, fts_ent->fts_namelen);
ofts_ent->path = malloc(ofts_ent->path_len + 1);
strncpy(ofts_ent->path, fts_ent->fts_path, ofts_ent->path_len);
ofts_ent->path[ofts_ent->path_len] = '\0';
ofts_ent->path_len = pathlen_from_ftse(fts_ent->fts_pathlen, fts_ent->fts_namelen) - shift;
if (ofts_ent->path_len > 0) {
ofts_ent->path = malloc(ofts_ent->path_len + 1);
strncpy(ofts_ent->path + shift, fts_ent->fts_path, ofts_ent->path_len);
ofts_ent->path[ofts_ent->path_len] = '\0';
} else {
ofts_ent->path_len = 1;
ofts_ent->path = strdup("/");
}

ofts_ent->file_len = fts_ent->fts_namelen;
ofts_ent->file = strdup(fts_ent->fts_name);
} else {
ofts_ent->path_len = fts_ent->fts_pathlen;
ofts_ent->path = strdup(fts_ent->fts_path);
ofts_ent->path_len = fts_ent->fts_pathlen - shift;
if (ofts_ent->path_len > 0) {
ofts_ent->path = strdup(fts_ent->fts_path + shift);
} else {
ofts_ent->path_len = 1;
ofts_ent->path = strdup("/");
}

ofts_ent->file_len = -1;
ofts_ent->file = NULL;
Expand Down Expand Up @@ -811,6 +822,12 @@ OVAL_FTS *oval_fts_open(const char *prefix, SEXP_t *path, SEXP_t *filename, SEXP
paths[0] = strdup("/");
}

if (prefix != NULL) {
char *path_with_prefix = oscap_sprintf("%s%s", prefix, paths[0]);
free((void *) paths[0]);
paths[0] = path_with_prefix;
}
dI("Opening file '%s'.", paths[0]);
/* Fail if the provided path doensn't actually exist. Symlinks
without targets are accepted. */
if (lstat(paths[0], &st) == -1) {
Expand All @@ -825,6 +842,8 @@ OVAL_FTS *oval_fts_open(const char *prefix, SEXP_t *path, SEXP_t *filename, SEXP
dI("Opening file '%s'.", paths[0]);

ofts = OVAL_FTS_new();
ofts->prefix = prefix;

/* reset errno as fts_open() doesn't do it itself. */
errno = 0;
ofts->ofts_match_path_fts = fts_open((char * const *) paths, mtc_fts_options, NULL);
Expand Down Expand Up @@ -991,7 +1010,9 @@ static FTSENT *oval_fts_read_match_path(OVAL_FTS *ofts)
|| (!ofts->ofts_sfilepath && fts_ent->fts_info != FTS_D))
continue;

stmp = SEXP_string_newf("%s", fts_ent->fts_path);
const size_t shift = ofts->prefix ? strlen(ofts->prefix) : 0;
stmp = SEXP_string_newf("%s", fts_ent->fts_path + shift);

if (ofts->ofts_sfilepath)
/* try to match filepath */
ores = probe_entobj_cmp(ofts->ofts_sfilepath, stmp);
Expand Down
1 change: 1 addition & 0 deletions src/OVAL/probes/oval_fts.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ typedef struct {
int filesystem;

fsdev_t *localdevs;
const char *prefix;
} OVAL_FTS;

#define OVAL_RECURSE_DIRECTION_NONE 0 /* default */
Expand Down

0 comments on commit f02d86d

Please sign in to comment.