Skip to content

Commit 007de74

Browse files
authored
Merge pull request #1431 from jan-cerny/offline_mode_fix
Move the chroot call to probe_worker
2 parents de47c0d + 4fd76c9 commit 007de74

File tree

4 files changed

+135
-141
lines changed

4 files changed

+135
-141
lines changed

src/OVAL/probes/probe/input_handler.c

Lines changed: 62 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -122,99 +122,86 @@ void *probe_input_handler(void *arg)
122122

123123
if (oid != NULL) {
124124
SEXP_VALIDATE(oid);
125+
probe_out = probe_rcache_sexp_get(probe->rcache, oid);
125126

126-
if (probe->offline_mode && probe->supported_offline_mode == PROBE_OFFLINE_NONE) {
127-
dW("Requested offline mode is not supported by %s.", probe->name);
128-
/* Return a dummy. */
129-
probe_out = probe_cobj_new(SYSCHAR_FLAG_NOT_APPLICABLE, NULL, NULL, NULL);
130-
probe_ret = 0;
131-
SEXP_free(oid);
127+
if (probe_out == NULL) { /* cache miss */
128+
SEXP_t *skip_flag, *obj_mask;
129+
130+
skip_flag = probe_obj_getattrval(probe_in, "skip_eval");
131+
obj_mask = probe_obj_getmask(probe_in);
132132
SEXP_free(probe_in);
133-
oid = NULL;
134133
probe_in = NULL;
135-
}
136-
else {
137-
probe_out = probe_rcache_sexp_get(probe->rcache, oid);
138-
139-
if (probe_out == NULL) { /* cache miss */
140-
SEXP_t *skip_flag, *obj_mask;
141134

142-
skip_flag = probe_obj_getattrval(probe_in, "skip_eval");
143-
obj_mask = probe_obj_getmask(probe_in);
144-
SEXP_free(probe_in);
145-
probe_in = NULL;
135+
if (skip_flag != NULL) {
136+
oval_syschar_collection_flag_t cobj_flag;
146137

147-
if (skip_flag != NULL) {
148-
oval_syschar_collection_flag_t cobj_flag;
138+
cobj_flag = SEXP_number_geti_32(skip_flag);
139+
probe_out = probe_cobj_new(cobj_flag, NULL, NULL, obj_mask);
149140

150-
cobj_flag = SEXP_number_geti_32(skip_flag);
151-
probe_out = probe_cobj_new(cobj_flag, NULL, NULL, obj_mask);
141+
if (probe_rcache_sexp_add(probe->rcache, oid, probe_out) != 0) {
142+
/* TODO */
143+
abort();
144+
}
152145

153-
if (probe_rcache_sexp_add(probe->rcache, oid, probe_out) != 0) {
154-
/* TODO */
155-
abort();
156-
}
146+
probe_ret = 0;
147+
SEXP_free(oid);
148+
SEXP_free(skip_flag);
149+
SEXP_free(obj_mask);
150+
} else {
157151

158-
probe_ret = 0;
159-
SEXP_free(oid);
160-
SEXP_free(skip_flag);
161-
SEXP_free(obj_mask);
152+
SEXP_free(oid);
153+
SEXP_free(skip_flag);
154+
SEXP_free(obj_mask);
155+
156+
probe_pwpair_t *pair = malloc(sizeof(probe_pwpair_t));
157+
pair->probe = probe;
158+
pair->pth = probe_worker_new();
159+
pair->pth->sid = SEAP_msg_id(seap_request);
160+
pair->pth->msg = seap_request;
161+
pair->pth->msg_handler = &probe_worker;
162+
163+
if (rbt_i32_add(probe->workers, pair->pth->sid, pair->pth, NULL) != 0) {
164+
/*
165+
* Getting here means that there is already a
166+
* thread handling the message with the given
167+
* ID.
168+
*/
169+
dW("Attempt to evaluate an object "
170+
"(ID=%u) " // TODO: 64b IDs
171+
"which is already being evaluated by an other thread.", pair->pth->sid);
172+
173+
free(pair->pth);
174+
free(pair);
175+
SEAP_msg_free(seap_request);
162176
} else {
177+
/* OK */
178+
179+
if (pthread_create(&pair->pth->tid, &pth_attr, &probe_worker_runfn, pair))
180+
{
181+
dE("Cannot start a new worker thread: %d, %s.", errno, strerror(errno));
163182

164-
SEXP_free(oid);
165-
SEXP_free(skip_flag);
166-
SEXP_free(obj_mask);
167-
168-
probe_pwpair_t *pair = malloc(sizeof(probe_pwpair_t));
169-
pair->probe = probe;
170-
pair->pth = probe_worker_new();
171-
pair->pth->sid = SEAP_msg_id(seap_request);
172-
pair->pth->msg = seap_request;
173-
pair->pth->msg_handler = &probe_worker;
174-
175-
if (rbt_i32_add(probe->workers, pair->pth->sid, pair->pth, NULL) != 0) {
176-
/*
177-
* Getting here means that there is already a
178-
* thread handling the message with the given
179-
* ID.
180-
*/
181-
dW("Attempt to evaluate an object "
182-
"(ID=%u) " // TODO: 64b IDs
183-
"which is already being evaluated by an other thread.", pair->pth->sid);
183+
if (rbt_i32_del(probe->workers, pair->pth->sid, NULL) != 0)
184+
dE("rbt_i32_del: failed to remove worker thread (ID=%u)", pair->pth->sid);
184185

186+
SEAP_msg_free(pair->pth->msg);
185187
free(pair->pth);
186188
free(pair);
187-
SEAP_msg_free(seap_request);
188-
} else {
189-
/* OK */
190189

191-
if (pthread_create(&pair->pth->tid, &pth_attr, &probe_worker_runfn, pair))
192-
{
193-
dE("Cannot start a new worker thread: %d, %s.", errno, strerror(errno));
190+
probe_ret = PROBE_EUNKNOWN;
191+
probe_out = NULL;
194192

195-
if (rbt_i32_del(probe->workers, pair->pth->sid, NULL) != 0)
196-
dE("rbt_i32_del: failed to remove worker thread (ID=%u)", pair->pth->sid);
197-
198-
SEAP_msg_free(pair->pth->msg);
199-
free(pair->pth);
200-
free(pair);
201-
202-
probe_ret = PROBE_EUNKNOWN;
203-
probe_out = NULL;
204-
205-
goto __error_reply;
206-
}
193+
goto __error_reply;
207194
}
208-
209-
seap_request = NULL;
210-
continue;
211195
}
212-
} else {
213-
/* cache hit */
214-
SEXP_free(oid);
215-
SEXP_free(probe_in);
216-
probe_ret = 0;
196+
197+
seap_request = NULL;
198+
continue;
217199
}
200+
} else {
201+
/* cache hit */
202+
SEXP_free(oid);
203+
SEXP_free(probe_in);
204+
probe_ret = 0;
218205
}
219206
} else {
220207
/* the `id' was not found in the input object */

src/OVAL/probes/probe/probe.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ typedef struct {
4747
pthread_rwlock_t rwlock;
4848
uint32_t flags;
4949

50-
char *name;
5150
pid_t pid;
5251

5352
void *probe_arg;

src/OVAL/probes/probe/probe_main.c

Lines changed: 0 additions & 65 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");
@@ -174,7 +158,6 @@ static void probe_common_main_cleanup(void *arg)
174158
rbt_i32_free(probe->workers);
175159
SEAP_CTX_free(probe->SEAP_ctx);
176160
free(probe->option);
177-
free(probe->name);
178161

179162
dD("probe_common_main_cleanup finished");
180163
}
@@ -183,7 +166,6 @@ void *probe_common_main(void *arg)
183166
{
184167
pthread_attr_t th_attr;
185168
probe_t probe;
186-
char *rootdir = NULL;
187169
struct probe_common_main_argument *probe_argument = (struct probe_common_main_argument *) arg;
188170
sch_queuedata_t *data = probe_argument->queuedata;
189171
oval_subtype_t subtype = probe_argument->subtype;
@@ -210,7 +192,6 @@ void *probe_common_main(void *arg)
210192
probe.selected_offline_mode = PROBE_OFFLINE_NONE;
211193
probe.flags = 0;
212194
probe.pid = getpid();
213-
probe.name = (char *) arg;
214195
probe.probe_exitcode = 0;
215196

216197
/*
@@ -250,52 +231,6 @@ void *probe_common_main(void *arg)
250231
OSCAP_GSYM(probe_optdef) = probe.option;
251232
OSCAP_GSYM(probe_optdef_count) = probe.optcnt;
252233

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
299234

300235
/*
301236
* 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,23 @@
4143
extern bool OSCAP_GSYM(varref_handling);
4244
extern void *OSCAP_GSYM(probe_arg);
4345

46+
// Dummy pthread routine
47+
static void *dummy_routine(void *dummy_param)
48+
{
49+
return NULL;
50+
}
51+
52+
static void preload_libraries_before_chroot()
53+
{
54+
// Force to load dynamic libraries used by pthread_cancel
55+
pthread_t t;
56+
if (pthread_create(&t, NULL, dummy_routine, NULL)) {
57+
dE("pthread_create failed: %s", strerror(errno));
58+
}
59+
pthread_cancel(t);
60+
pthread_join(t, NULL);
61+
}
62+
4463
void *probe_worker_runfn(void *arg)
4564
{
4665
dD("probe_worker_runfn has started");
@@ -945,6 +964,60 @@ static SEXP_t *probe_set_eval(probe_t *probe, SEXP_t *set, size_t depth)
945964
*/
946965
SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
947966
{
967+
#ifndef OS_WINDOWS
968+
char *rootdir = NULL;
969+
probe_offline_mode_function_t offline_mode_function = probe_table_get_offline_mode_function(probe->subtype);
970+
if (offline_mode_function != NULL) {
971+
probe->supported_offline_mode = offline_mode_function();
972+
}
973+
974+
/*
975+
* Setup offline mode(s)
976+
*/
977+
rootdir = getenv("OSCAP_PROBE_ROOT");
978+
if ((rootdir != NULL) && (strlen(rootdir) > 0)) {
979+
preload_libraries_before_chroot(); // todo - maybe useless for own mode
980+
981+
if (probe->supported_offline_mode == PROBE_OFFLINE_NONE) {
982+
dW("Requested offline mode is not supported by %s probe.", oval_subtype_get_text(probe->subtype));
983+
*ret = 0;
984+
return probe_cobj_new(SYSCHAR_FLAG_NOT_APPLICABLE, NULL, NULL, NULL);
985+
986+
} else if (probe->supported_offline_mode & PROBE_OFFLINE_OWN) {
987+
dI("Switching probe to PROBE_OFFLINE_OWN mode.");
988+
probe->offline_mode = true;
989+
probe->selected_offline_mode = PROBE_OFFLINE_OWN;
990+
991+
} else if (probe->supported_offline_mode & PROBE_OFFLINE_CHROOT) {
992+
probe->real_root_fd = open("/", O_RDONLY);
993+
probe->real_cwd_fd = open(".", O_RDONLY);
994+
if (chdir(rootdir) != 0) {
995+
dE("chdir failed: %s", strerror(errno));
996+
}
997+
998+
if (chroot(rootdir) != 0) {
999+
dE("chroot failed: %s", strerror(errno));
1000+
}
1001+
/* NOTE: We're running in a different root directory.
1002+
* Unless /proc, /sys are somehow emulated for the new
1003+
* environment, they are not relevant and so are other
1004+
* runtime only things (e.g. getenv, uname, ...).
1005+
* Switch to offline mode. We may add a separate
1006+
* mechanism to control this behaviour in the future.
1007+
*/
1008+
dI("Switching probe to PROBE_OFFLINE_CHROOT mode.");
1009+
probe->offline_mode = true;
1010+
probe->selected_offline_mode = PROBE_OFFLINE_CHROOT;
1011+
}
1012+
}
1013+
1014+
if (getenv("OSCAP_PROBE_RPMDB_PATH") != NULL) {
1015+
dI("Switching probe to PROBE_OFFLINE_RPMDB mode.");
1016+
probe->offline_mode = true;
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)