Skip to content

Commit e299045

Browse files
committed
Move the chroot call to probe_worker
We have discovered a problem when testing offline mode in the symlink probe. When the probe main function needs to be executed multiple times, function `probe_common_main`, where the chroot is entered, is called only once, but function `probe_worker`, which leaves the chroot, is called many times. This leads to a situation that the first OVAL test is evaluated in chroot, but all further tests have retrieved data from the host. Therefore the collected data were wrong. We try to address this problem by moving the code.
1 parent de47c0d commit e299045

File tree

2 files changed

+73
-63
lines changed

2 files changed

+73
-63
lines changed

src/OVAL/probes/probe/probe_main.c

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,6 @@ static int probe_opthandler_rcache(int option, int op, va_list args)
130130
return (0);
131131
}
132132

133-
// Dummy pthread routine
134-
static void * dummy_routine(void *dummy_param)
135-
{
136-
return NULL;
137-
}
138-
139-
static void preload_libraries_before_chroot()
140-
{
141-
// Force to load dynamic libraries used by pthread_cancel
142-
pthread_t t;
143-
if (pthread_create(&t, NULL, dummy_routine, NULL))
144-
fail(errno, "pthread_create(probe_preload)", __LINE__ - 1);
145-
pthread_cancel(t);
146-
pthread_join(t, NULL);
147-
}
148-
149133
static void probe_common_main_cleanup(void *arg)
150134
{
151135
dD("probe_common_main_cleanup started");
@@ -183,7 +167,6 @@ void *probe_common_main(void *arg)
183167
{
184168
pthread_attr_t th_attr;
185169
probe_t probe;
186-
char *rootdir = NULL;
187170
struct probe_common_main_argument *probe_argument = (struct probe_common_main_argument *) arg;
188171
sch_queuedata_t *data = probe_argument->queuedata;
189172
oval_subtype_t subtype = probe_argument->subtype;
@@ -250,52 +233,6 @@ void *probe_common_main(void *arg)
250233
OSCAP_GSYM(probe_optdef) = probe.option;
251234
OSCAP_GSYM(probe_optdef_count) = probe.optcnt;
252235

253-
#ifndef OS_WINDOWS
254-
probe_offline_mode_function_t offline_mode_function = probe_table_get_offline_mode_function(probe.subtype);
255-
if (offline_mode_function != NULL) {
256-
probe.supported_offline_mode = offline_mode_function();
257-
}
258-
259-
/*
260-
* Setup offline mode(s)
261-
*/
262-
rootdir = getenv("OSCAP_PROBE_ROOT");
263-
if ((rootdir != NULL) && (strlen(rootdir) > 0)) {
264-
probe.offline_mode = true;
265-
266-
preload_libraries_before_chroot(); // todo - maybe useless for own mode
267-
268-
if (probe.supported_offline_mode & PROBE_OFFLINE_OWN) {
269-
dI("Swiching probe to PROBE_OFFLINE_OWN mode.");
270-
probe.selected_offline_mode = PROBE_OFFLINE_OWN;
271-
272-
} else if (probe.supported_offline_mode & PROBE_OFFLINE_CHROOT) {
273-
probe.real_root_fd = open("/", O_RDONLY);
274-
probe.real_cwd_fd = open(".", O_RDONLY);
275-
if (chdir(rootdir) != 0) {
276-
fail(errno, "chdir", __LINE__ -1);
277-
}
278-
279-
if (chroot(rootdir) != 0) {
280-
fail(errno, "chroot", __LINE__ - 1);
281-
}
282-
/* NOTE: We're running in a different root directory.
283-
* Unless /proc, /sys are somehow emulated for the new
284-
* environment, they are not relevant and so are other
285-
* runtime only things (e.g. getenv, uname, ...).
286-
* Switch to offline mode. We may add a separate
287-
* mechanism to control this behaviour in the future.
288-
*/
289-
dI("Swiching probe to PROBE_OFFLINE_CHROOT mode.");
290-
probe.selected_offline_mode = PROBE_OFFLINE_CHROOT;
291-
}
292-
}
293-
294-
if (getenv("OSCAP_PROBE_RPMDB_PATH") != NULL) {
295-
dI("Swiching probe to PROBE_OFFLINE_RPMDB mode.");
296-
probe.selected_offline_mode = PROBE_OFFLINE_RPMDB;
297-
}
298-
#endif
299236

300237
/*
301238
* Create input handler (detached)

src/OVAL/probes/probe/worker.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#endif
2626

2727
#include "_seap.h"
28+
#include <stdio.h>
29+
#include <fcntl.h>
2830
#include <stdlib.h>
2931
#include <string.h>
3032
#include <pthread.h>
@@ -41,6 +43,29 @@
4143
extern bool OSCAP_GSYM(varref_handling);
4244
extern void *OSCAP_GSYM(probe_arg);
4345

46+
47+
static int fail(int err, const char *who, int line)
48+
{
49+
fprintf(stderr, "FAIL: %d:%s: %d, %s\n", line, who, err, strerror(err));
50+
exit(err);
51+
}
52+
53+
// Dummy pthread routine
54+
static void *dummy_routine(void *dummy_param)
55+
{
56+
return NULL;
57+
}
58+
59+
static void preload_libraries_before_chroot()
60+
{
61+
// Force to load dynamic libraries used by pthread_cancel
62+
pthread_t t;
63+
if (pthread_create(&t, NULL, dummy_routine, NULL))
64+
fail(errno, "pthread_create(probe_preload)", __LINE__ - 1);
65+
pthread_cancel(t);
66+
pthread_join(t, NULL);
67+
}
68+
4469
void *probe_worker_runfn(void *arg)
4570
{
4671
dD("probe_worker_runfn has started");
@@ -945,6 +970,54 @@ static SEXP_t *probe_set_eval(probe_t *probe, SEXP_t *set, size_t depth)
945970
*/
946971
SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
947972
{
973+
#ifndef OS_WINDOWS
974+
char *rootdir = NULL;
975+
probe_offline_mode_function_t offline_mode_function = probe_table_get_offline_mode_function(probe->subtype);
976+
if (offline_mode_function != NULL) {
977+
probe->supported_offline_mode = offline_mode_function();
978+
}
979+
980+
/*
981+
* Setup offline mode(s)
982+
*/
983+
rootdir = getenv("OSCAP_PROBE_ROOT");
984+
if ((rootdir != NULL) && (strlen(rootdir) > 0)) {
985+
probe->offline_mode = true;
986+
987+
preload_libraries_before_chroot(); // todo - maybe useless for own mode
988+
989+
if (probe->supported_offline_mode & PROBE_OFFLINE_OWN) {
990+
dI("Switching probe to PROBE_OFFLINE_OWN mode.");
991+
probe->selected_offline_mode = PROBE_OFFLINE_OWN;
992+
993+
} else if (probe->supported_offline_mode & PROBE_OFFLINE_CHROOT) {
994+
probe->real_root_fd = open("/", O_RDONLY);
995+
probe->real_cwd_fd = open(".", O_RDONLY);
996+
if (chdir(rootdir) != 0) {
997+
fail(errno, "chdir", __LINE__ -1);
998+
}
999+
1000+
if (chroot(rootdir) != 0) {
1001+
fail(errno, "chroot", __LINE__ - 1);
1002+
}
1003+
/* NOTE: We're running in a different root directory.
1004+
* Unless /proc, /sys are somehow emulated for the new
1005+
* environment, they are not relevant and so are other
1006+
* runtime only things (e.g. getenv, uname, ...).
1007+
* Switch to offline mode. We may add a separate
1008+
* mechanism to control this behaviour in the future.
1009+
*/
1010+
dI("Switching probe to PROBE_OFFLINE_CHROOT mode.");
1011+
probe->selected_offline_mode = PROBE_OFFLINE_CHROOT;
1012+
}
1013+
}
1014+
1015+
if (getenv("OSCAP_PROBE_RPMDB_PATH") != NULL) {
1016+
dI("Switching probe to PROBE_OFFLINE_RPMDB mode.");
1017+
probe->selected_offline_mode = PROBE_OFFLINE_RPMDB;
1018+
}
1019+
#endif
1020+
9481021
SEXP_t *probe_in, *probe_out, *set;
9491022

9501023
if (msg_in == NULL) {

0 commit comments

Comments
 (0)