|
25 | 25 | #endif
|
26 | 26 |
|
27 | 27 | #include "_seap.h"
|
| 28 | +#include <stdio.h> |
| 29 | +#include <fcntl.h> |
28 | 30 | #include <stdlib.h>
|
29 | 31 | #include <string.h>
|
30 | 32 | #include <pthread.h>
|
|
41 | 43 | extern bool OSCAP_GSYM(varref_handling);
|
42 | 44 | extern void *OSCAP_GSYM(probe_arg);
|
43 | 45 |
|
| 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 | + |
44 | 69 | void *probe_worker_runfn(void *arg)
|
45 | 70 | {
|
46 | 71 | 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)
|
945 | 970 | */
|
946 | 971 | SEXP_t *probe_worker(probe_t *probe, SEAP_msg_t *msg_in, int *ret)
|
947 | 972 | {
|
| 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 | + |
948 | 1021 | SEXP_t *probe_in, *probe_out, *set;
|
949 | 1022 |
|
950 | 1023 | if (msg_in == NULL) {
|
|
0 commit comments