Skip to content

Commit

Permalink
Use and return canonical paths in rpmverifyfile probe
Browse files Browse the repository at this point in the history
This is done to prevent false positives in implementation of rules
file_permissions_unauthorized_suid and
file_permissions_unauthorized_sgid proposed in ComplianceAsCode
in ComplianceAsCode/content#4648
caused by inconsistent symlink usage in rpmdb.

Also improves logic when an exact file path is defined in
rpmverifyfile_object we don't have to iterate over all RPMs in the
rpmdb but we query the rpmdb directly.
  • Loading branch information
jan-cerny committed Oct 25, 2019
1 parent 490983b commit 3beda86
Showing 1 changed file with 35 additions and 11 deletions.
46 changes: 35 additions & 11 deletions src/OVAL/probes/unix/linux/rpmverifyfile_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <pcre.h>

#include "rpm-helper.h"
#include "oscap_helpers.h"

/* Individual RPM headers */
#include <rpm/rpmfi.h>
Expand Down Expand Up @@ -134,6 +135,7 @@ static int rpmverify_collect(probe_ctx *ctx,
Header pkgh;
pcre *re = NULL;
int ret = -1;
char *file_realpath = NULL;

/* pre-compile regex if needed */
if (file_op == OVAL_OPERATION_PATTERN_MATCH) {
Expand All @@ -150,7 +152,16 @@ static int rpmverify_collect(probe_ctx *ctx,

RPMVERIFY_LOCK;

match = rpmtsInitIterator(g_rpm->rpmts, RPMDBI_PACKAGES, NULL, 0);
if (file != NULL && file_op == OVAL_OPERATION_EQUALS) {
/*
* When we know the exact file path we look for, we don't need to
* filter all RPM packages, but we can ask the rpmdb directly for
* the package which provides this file, similar to `rpm -q -f`.
*/
match = rpmtsInitIterator(g_rpm->rpmts, RPMDBI_INSTFILENAMES, file, 0);
} else {
match = rpmtsInitIterator(g_rpm->rpmts, RPMDBI_PACKAGES, NULL, 0);
}
if (match == NULL) {
ret = 0;
goto ret;
Expand Down Expand Up @@ -181,13 +192,17 @@ static int rpmverify_collect(probe_ctx *ctx,
return -1;
}

file_realpath = oscap_realpath(file, NULL);

while ((pkgh = rpmdbNextIterator (match)) != NULL) {
SEXP_t *ent;
rpmfi fi;
rpmTag tag[2] = { RPMTAG_BASENAMES, RPMTAG_DIRNAMES };
struct rpmverify_res res;
errmsg_t rpmerr;
int i;
const char *current_file;
char *current_file_realpath;

/*
+SEXP_t *probe_ent_from_cstr(const char *name, oval_datatype_t type,
Expand Down Expand Up @@ -229,51 +244,59 @@ static int rpmverify_collect(probe_ctx *ctx,
fi = rpmfiNew(g_rpm->rpmts, pkgh, tag[i], 1);

while (rpmfiNext(fi) != -1) {
res.file = oscap_strdup(rpmfiFN(fi));
current_file = rpmfiFN(fi);
current_file_realpath = oscap_realpath(current_file, NULL);
res.fflags = rpmfiFFlags(fi);
res.oflags = omit;

if (((res.fflags & RPMFILE_CONFIG) && (flags & RPMVERIFY_SKIP_CONFIG)) ||
((res.fflags & RPMFILE_GHOST) && (flags & RPMVERIFY_SKIP_GHOST))) {
free(res.file);
free(current_file_realpath);
continue;
}

switch(file_op) {
case OVAL_OPERATION_EQUALS:
if (strcmp(res.file, file) != 0) {
free(res.file);
if (strcmp(current_file, file) != 0 &&
current_file_realpath && file_realpath &&
strcmp(current_file_realpath, file_realpath) != 0) {
free(current_file_realpath);
continue;
}
res.file = oscap_strdup(file);
break;
case OVAL_OPERATION_NOT_EQUAL:
if (strcmp(res.file, file) == 0) {
free(res.file);
if (strcmp(current_file, file) == 0 ||
(current_file_realpath && file_realpath &&
strcmp(current_file_realpath, file_realpath) == 0)) {
free(current_file_realpath);
continue;
}
res.file = current_file_realpath ? current_file_realpath : strdup(current_file);
break;
case OVAL_OPERATION_PATTERN_MATCH:
ret = pcre_exec(re, NULL, res.file, strlen(res.file), 0, 0, NULL, 0);
ret = pcre_exec(re, NULL, current_file, strlen(current_file), 0, 0, NULL, 0);

switch(ret) {
case 0: /* match */
res.file = strdup(current_file);
break;
case -1:
/* mismatch */
free(res.file);
free(current_file_realpath);
continue;
default:
dE("pcre_exec() failed!");
ret = -1;
free(res.file);
free(current_file_realpath);
goto ret;
}
break;
default:
/* unsupported operation */
dE("Operation \"%d\" on `filepath' not supported", file_op);
ret = -1;
free(res.file);
free(current_file_realpath);
goto ret;
}

Expand All @@ -299,6 +322,7 @@ static int rpmverify_collect(probe_ctx *ctx,
pcre_free(re);

RPMVERIFY_UNLOCK;
free(file_realpath);
return (ret);
}

Expand Down

0 comments on commit 3beda86

Please sign in to comment.