44
44
#include <pcre.h>
45
45
46
46
#include "rpm-helper.h"
47
+ #include "oscap_helpers.h"
47
48
48
49
/* Individual RPM headers */
49
50
#include <rpm/rpmfi.h>
@@ -134,6 +135,7 @@ static int rpmverify_collect(probe_ctx *ctx,
134
135
Header pkgh ;
135
136
pcre * re = NULL ;
136
137
int ret = -1 ;
138
+ char * file_realpath = NULL ;
137
139
138
140
/* pre-compile regex if needed */
139
141
if (file_op == OVAL_OPERATION_PATTERN_MATCH ) {
@@ -150,7 +152,16 @@ static int rpmverify_collect(probe_ctx *ctx,
150
152
151
153
RPMVERIFY_LOCK ;
152
154
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
+ }
154
165
if (match == NULL ) {
155
166
ret = 0 ;
156
167
goto ret ;
@@ -181,13 +192,17 @@ static int rpmverify_collect(probe_ctx *ctx,
181
192
return -1 ;
182
193
}
183
194
195
+ file_realpath = oscap_realpath (file , NULL );
196
+
184
197
while ((pkgh = rpmdbNextIterator (match )) != NULL ) {
185
198
SEXP_t * ent ;
186
199
rpmfi fi ;
187
200
rpmTag tag [2 ] = { RPMTAG_BASENAMES , RPMTAG_DIRNAMES };
188
201
struct rpmverify_res res ;
189
202
errmsg_t rpmerr ;
190
203
int i ;
204
+ const char * current_file ;
205
+ char * current_file_realpath ;
191
206
192
207
/*
193
208
+SEXP_t *probe_ent_from_cstr(const char *name, oval_datatype_t type,
@@ -229,51 +244,59 @@ static int rpmverify_collect(probe_ctx *ctx,
229
244
fi = rpmfiNew (g_rpm -> rpmts , pkgh , tag [i ], 1 );
230
245
231
246
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 );
233
249
res .fflags = rpmfiFFlags (fi );
234
250
res .oflags = omit ;
235
251
236
252
if (((res .fflags & RPMFILE_CONFIG ) && (flags & RPMVERIFY_SKIP_CONFIG )) ||
237
253
((res .fflags & RPMFILE_GHOST ) && (flags & RPMVERIFY_SKIP_GHOST ))) {
238
- free (res . file );
254
+ free (current_file_realpath );
239
255
continue ;
240
256
}
241
257
242
258
switch (file_op ) {
243
259
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 );
246
264
continue ;
247
265
}
266
+ res .file = oscap_strdup (file );
248
267
break ;
249
268
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 );
252
273
continue ;
253
274
}
275
+ res .file = current_file_realpath ? current_file_realpath : strdup (current_file );
254
276
break ;
255
277
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 );
257
279
258
280
switch (ret ) {
259
281
case 0 : /* match */
282
+ res .file = strdup (current_file );
260
283
break ;
261
284
case -1 :
262
285
/* mismatch */
263
- free (res . file );
286
+ free (current_file_realpath );
264
287
continue ;
265
288
default :
266
289
dE ("pcre_exec() failed!" );
267
290
ret = -1 ;
268
- free (res . file );
291
+ free (current_file_realpath );
269
292
goto ret ;
270
293
}
271
294
break ;
272
295
default :
273
296
/* unsupported operation */
274
297
dE ("Operation \"%d\" on `filepath' not supported" , file_op );
275
298
ret = -1 ;
276
- free (res . file );
299
+ free (current_file_realpath );
277
300
goto ret ;
278
301
}
279
302
@@ -299,6 +322,7 @@ static int rpmverify_collect(probe_ctx *ctx,
299
322
pcre_free (re );
300
323
301
324
RPMVERIFY_UNLOCK ;
325
+ free (file_realpath );
302
326
return (ret );
303
327
}
304
328
0 commit comments