Skip to content

Commit 156c8b5

Browse files
authored
Merge pull request #1412 from jan-cerny/rpmverifyfile_path_canonical
Use and return canonical paths in rpmverifyfile probe
2 parents da4610e + 3beda86 commit 156c8b5

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed

src/OVAL/probes/unix/linux/rpmverifyfile_probe.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <pcre.h>
4545

4646
#include "rpm-helper.h"
47+
#include "oscap_helpers.h"
4748

4849
/* Individual RPM headers */
4950
#include <rpm/rpmfi.h>
@@ -134,6 +135,7 @@ static int rpmverify_collect(probe_ctx *ctx,
134135
Header pkgh;
135136
pcre *re = NULL;
136137
int ret = -1;
138+
char *file_realpath = NULL;
137139

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

151153
RPMVERIFY_LOCK;
152154

153-
match = rpmtsInitIterator(g_rpm->rpmts, RPMDBI_PACKAGES, NULL, 0);
155+
if (file != NULL && file_op == OVAL_OPERATION_EQUALS) {
156+
/*
157+
* When we know the exact file path we look for, we don't need to
158+
* filter all RPM packages, but we can ask the rpmdb directly for
159+
* the package which provides this file, similar to `rpm -q -f`.
160+
*/
161+
match = rpmtsInitIterator(g_rpm->rpmts, RPMDBI_INSTFILENAMES, file, 0);
162+
} else {
163+
match = rpmtsInitIterator(g_rpm->rpmts, RPMDBI_PACKAGES, NULL, 0);
164+
}
154165
if (match == NULL) {
155166
ret = 0;
156167
goto ret;
@@ -181,13 +192,17 @@ static int rpmverify_collect(probe_ctx *ctx,
181192
return -1;
182193
}
183194

195+
file_realpath = oscap_realpath(file, NULL);
196+
184197
while ((pkgh = rpmdbNextIterator (match)) != NULL) {
185198
SEXP_t *ent;
186199
rpmfi fi;
187200
rpmTag tag[2] = { RPMTAG_BASENAMES, RPMTAG_DIRNAMES };
188201
struct rpmverify_res res;
189202
errmsg_t rpmerr;
190203
int i;
204+
const char *current_file;
205+
char *current_file_realpath;
191206

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

231246
while (rpmfiNext(fi) != -1) {
232-
res.file = oscap_strdup(rpmfiFN(fi));
247+
current_file = rpmfiFN(fi);
248+
current_file_realpath = oscap_realpath(current_file, NULL);
233249
res.fflags = rpmfiFFlags(fi);
234250
res.oflags = omit;
235251

236252
if (((res.fflags & RPMFILE_CONFIG) && (flags & RPMVERIFY_SKIP_CONFIG)) ||
237253
((res.fflags & RPMFILE_GHOST) && (flags & RPMVERIFY_SKIP_GHOST))) {
238-
free(res.file);
254+
free(current_file_realpath);
239255
continue;
240256
}
241257

242258
switch(file_op) {
243259
case OVAL_OPERATION_EQUALS:
244-
if (strcmp(res.file, file) != 0) {
245-
free(res.file);
260+
if (strcmp(current_file, file) != 0 &&
261+
current_file_realpath && file_realpath &&
262+
strcmp(current_file_realpath, file_realpath) != 0) {
263+
free(current_file_realpath);
246264
continue;
247265
}
266+
res.file = oscap_strdup(file);
248267
break;
249268
case OVAL_OPERATION_NOT_EQUAL:
250-
if (strcmp(res.file, file) == 0) {
251-
free(res.file);
269+
if (strcmp(current_file, file) == 0 ||
270+
(current_file_realpath && file_realpath &&
271+
strcmp(current_file_realpath, file_realpath) == 0)) {
272+
free(current_file_realpath);
252273
continue;
253274
}
275+
res.file = current_file_realpath ? current_file_realpath : strdup(current_file);
254276
break;
255277
case OVAL_OPERATION_PATTERN_MATCH:
256-
ret = pcre_exec(re, NULL, res.file, strlen(res.file), 0, 0, NULL, 0);
278+
ret = pcre_exec(re, NULL, current_file, strlen(current_file), 0, 0, NULL, 0);
257279

258280
switch(ret) {
259281
case 0: /* match */
282+
res.file = strdup(current_file);
260283
break;
261284
case -1:
262285
/* mismatch */
263-
free(res.file);
286+
free(current_file_realpath);
264287
continue;
265288
default:
266289
dE("pcre_exec() failed!");
267290
ret = -1;
268-
free(res.file);
291+
free(current_file_realpath);
269292
goto ret;
270293
}
271294
break;
272295
default:
273296
/* unsupported operation */
274297
dE("Operation \"%d\" on `filepath' not supported", file_op);
275298
ret = -1;
276-
free(res.file);
299+
free(current_file_realpath);
277300
goto ret;
278301
}
279302

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

301324
RPMVERIFY_UNLOCK;
325+
free(file_realpath);
302326
return (ret);
303327
}
304328

0 commit comments

Comments
 (0)