19262735 The file probe needs to be zone aware
19173594 oscap crashes when compliance is run
19559867 compliance fails when no network interface are defined
This patch fixes an issue with file probe on solaris. The file probe currently
is not zone aware and so descends into non-global zones from the global-zone.
Fix prevents file probe traversal into non-global zones from the global zone,
when local is specified for recursion.
This patch has not been contributed upstream, but is planned to be submitted by
2014-Oct-15.
--- openscap-1.0.0/src/OVAL/probes/oval_fts.c.~2~ 2014-07-24 10:53:15.269589073 -0700
+++ openscap-1.0.0/src/OVAL/probes/oval_fts.c 2014-07-24 11:02:30.267608422 -0700
@@ -45,6 +45,8 @@
#if defined(__SVR4) && defined(__sun)
#include "fts_sun.h"
#include <sys/mntent.h>
+#include <libzonecfg.h>
+#include <sys/avl.h>
#else
#include <fts.h>
#endif
@@ -138,6 +140,13 @@
#define MNTTYPE_PROC "proc"
#endif
+typedef struct zone_path {
+ avl_node_t avl_link_next;
+ char zpath[MAXPATHLEN];
+} zone_path_t;
+static avl_tree_t avl_tree_list;
+
+
static bool valid_remote_fs(char *fstype)
{
if (strcmp(fstype, MNTTYPE_NFS) == 0 ||
@@ -160,6 +169,85 @@
return (false);
return (true);
}
+
+/* function to compare two avl nodes in the avl tree */
+static int compare_zoneroot(const void *entry1, const void *entry2)
+{
+ zone_path_t *t1, *t2;
+ int comp;
+
+ t1 = (zone_path_t *)entry1;
+ t2 = (zone_path_t *)entry2;
+ if ((comp = strcmp(t1->zpath, t2->zpath)) == 0) {
+ return (0);
+ }
+ return (comp > 0 ? 1 : -1);
+}
+
+int load_zones_path_list()
+{
+ FILE *cookie;
+ char *name;
+ zone_state_t state_num;
+ zone_path_t *temp = NULL;
+ avl_index_t where;
+ char rpath[MAXPATHLEN];
+
+ cookie = setzoneent();
+ if (getzoneid() != GLOBAL_ZONEID)
+ return (0);
+ avl_create(&avl_tree_list, compare_zoneroot,
+ sizeof(zone_path_t), offsetof(zone_path_t, avl_link_next));
+ while ((name = getzoneent(cookie)) != NULL) {
+ if (strcmp(name, "global") == 0)
+ continue;
+ if (zone_get_state(name, &state_num) != Z_OK) {
+ dE("Could not get zone state for %s\n", name);
+ continue;
+ } else if (state_num > ZONE_STATE_CONFIGURED) {
+ temp = malloc(sizeof(zone_path_t));
+ if (temp == NULL) {
+ dE("Memory alloc failed\n");
+ return(1);
+ }
+ if (zone_get_zonepath(name, rpath,
+ sizeof(rpath)) != Z_OK) {
+ dE("Could not get zone path for %s\n",
+ name);
+ continue;
+ }
+ if (realpath(rpath, temp->zpath) != NULL)
+ avl_add(&avl_tree_list, temp);
+ }
+ }
+ endzoneent(cookie);
+ return (0);
+}
+
+static void free_zones_path_list()
+{
+ zone_path_t *temp;
+ void* cookie = NULL;
+
+ while ((temp = avl_destroy_nodes(&avl_tree_list, &cookie)) != NULL) {
+ free(temp);
+ }
+ avl_destroy(&avl_tree_list);
+}
+
+static bool valid_local_zone(char *path)
+{
+ zone_path_t temp;
+ avl_index_t where;
+
+ strlcpy(temp.zpath, path, sizeof(temp.zpath));
+ if (avl_find(&avl_tree_list, &temp, &where) != NULL)
+ return (true);
+
+ return (false);
+}
+
+
#endif
static bool OVAL_FTS_localp(OVAL_FTS *ofts, const char *path, void *id)
@@ -168,9 +256,11 @@
if (id != NULL && (*(char*)id) != '\0') {
/* if not a valid local fs skip */
if (valid_local_fs((char*)id)) {
- /* if recurse is local , skip remote fs */
+ /* if recurse is local , skip remote fs
+ and non-global zones */
if (ofts->filesystem == OVAL_RECURSE_FS_LOCAL) {
- return (!valid_remote_fs((char*)id));
+ return (!(valid_remote_fs((char*)id) ||
+ valid_local_zone(path)));
}
return (true);
}
@@ -179,9 +269,11 @@
/* id was not set, because fts_read failed to stat the node */
struct stat sb;
if ((stat(path, &sb) == 0) && (valid_local_fs(sb.st_fstype))) {
- /* if recurse is local , skip remote fs */
+ /* if recurse is local , skip remote fs
+ and non-global zones */
if (ofts->filesystem == OVAL_RECURSE_FS_LOCAL) {
- return (!valid_remote_fs(sb.st_fstype));
+ return (!(valid_remote_fs(sb.st_fstype) ||
+ valid_local_zone(path)));
}
return (true);
}
@@ -793,6 +884,12 @@
ofts->ofts_sfilepath = SEXP_ref(filepath);
}
+#if defined(__SVR4) && defined(__sun)
+ if (load_zones_path_list() != 0) {
+ dE("Failed to load zones path info. Recursing non-global zones.");
+ free_zones_path_list();
+ }
+#endif
return (ofts);
}
@@ -1249,6 +1346,9 @@
fsdev_free(ofts->localdevs);
OVAL_FTS_free(ofts);
+#if defined(__SVR4) && defined(__sun)
+ free_zones_path_list();
+#endif
return (0);
}