diff --git a/tests/include/sepol_wrap.h b/tests/include/sepol_wrap.h index 2357421c70a376d38184b29324ba3a7725089c7c..0be2c1726eb9448b1557f0bf3f600f93032c1f0a 100644 --- a/tests/include/sepol_wrap.h +++ b/tests/include/sepol_wrap.h @@ -15,6 +15,9 @@ void destroy_expanded_avtab(void *avtab_iterp); int get_type(char *out, size_t max_size, void *policydbp, void *type_iterp); void *init_type_iter(void *policydbp, const char *type, bool is_attr); void destroy_type_iter(void *type_iterp); +void *init_genfs_iter(void *policydbp); +int get_genfs(char *out, size_t max_size, void *policydbp, void *genfs_iterp); +void destroy_genfs_iter(void *genfs_iterp); #ifdef __cplusplus } diff --git a/tests/policy.py b/tests/policy.py index b51ebf2370548f8a933408968b25b953d10b334f..90e387fb9f0877b9cbddf86d4b1b155519f202ce 100644 --- a/tests/policy.py +++ b/tests/policy.py @@ -47,6 +47,7 @@ class Policy: __Rules = set() __FcDict = None __FcSorted = None + __GenfsDict = None __libsepolwrap = None __policydbP = None __BUFSIZE = 2048 @@ -66,6 +67,21 @@ class Policy: ret += " ".join(str(x) for x in sorted(violators)) + "\n" return ret + # Check that all types for "filesystem" have "attribute" associated with them + # for types labeled in genfs_contexts. + def AssertGenfsFilesystemTypesHaveAttr(self, Filesystem, Attr): + TypesPol = self.QueryTypeAttribute(Attr, True) + TypesGenfs = self.__GenfsDict[Filesystem] + violators = TypesGenfs.difference(TypesPol) + + ret = "" + if len(violators) > 0: + ret += "The following types in " + Filesystem + ret += " must be associated with the " + ret += "\"" + Attr + "\" attribute: " + ret += " ".join(str(x) for x in sorted(violators)) + "\n" + return ret + # Check that path prefixes that match MatchPrefix, and do not Match # DoNotMatchPrefix have the attribute Attr. # For example assert that all types in /sys, and not in /sys/kernel/debugfs @@ -337,9 +353,43 @@ class Policy: lib.init_type_iter.argtypes = [c_void_p, c_char_p, c_bool] # void destroy_type_iter(void *type_iterp); lib.destroy_type_iter.argtypes = [c_void_p] + # void *init_genfs_iter(void *policydbp) + lib.init_genfs_iter.restype = c_void_p + lib.init_genfs_iter.argtypes = [c_void_p] + # int get_genfs(char *out, size_t max_size, void *genfs_iterp); + lib.get_genfs.restype = c_int + lib.get_genfs.argtypes = [c_char_p, c_size_t, c_void_p, c_void_p] + # void destroy_genfs_iter(void *genfs_iterp) + lib.destroy_genfs_iter.argtypes = [c_void_p] self.__libsepolwrap = lib + def __GenfsDictAdd(self, Dict, buf): + fs, path, context = buf.split(" ") + Type = context.split(":")[2] + if not fs in Dict: + Dict[fs] = {Type} + else: + Dict[fs].add(Type) + + def __InitGenfsCon(self): + self.__GenfsDict = {} + GenfsIterP = self.__libsepolwrap.init_genfs_iter(self.__policydbP) + if (GenfsIterP == None): + sys.exit("Failed to retreive genfs entries") + buf = create_string_buffer(self.__BUFSIZE) + while True: + ret = self.__libsepolwrap.get_genfs(buf, self.__BUFSIZE, + self.__policydbP, GenfsIterP) + if ret == 0: + self.__GenfsDictAdd(self.__GenfsDict, buf.value) + continue + if ret == 1: + self.__GenfsDictAdd(self.__GenfsDict, buf.value) + break; + # We should never get here. + sys.exit("Failed to get genfs entries") + self.__libsepolwrap.destroy_genfs_iter(GenfsIterP) # load file_contexts def __InitFC(self, FcPaths): @@ -376,6 +426,7 @@ class Policy: self.__InitLibsepolwrap(LibPath) self.__InitFC(FcPaths) self.__InitPolicy(PolicyPath) + self.__InitGenfsCon() def __del__(self): if self.__policydbP is not None: diff --git a/tests/sepol_wrap.cpp b/tests/sepol_wrap.cpp index d537b7e00f242506e7fb9fbb927f0d454b309a78..39b618b9064fb5f7a1f0159601dd801c58aebd12 100644 --- a/tests/sepol_wrap.cpp +++ b/tests/sepol_wrap.cpp @@ -17,6 +17,73 @@ #include <android-base/strings.h> #include <sepol_wrap.h> +struct genfs_iter { + genfs_t *genfs; + ocontext_t *ocon; +}; + +void *init_genfs_iter(void *policydbp) +{ + struct genfs_iter *out = (struct genfs_iter *) + calloc(1, sizeof(struct genfs_iter)); + + if (!out) { + std::cerr << "Failed to allocate genfs iterator" << std::endl; + return NULL; + } + + policydb_t *db = static_cast<policydb_t *>(policydbp); + + out->genfs = db->genfs; + out->ocon = db->genfs->head; + + return static_cast<void *>(out); +} + +/* + * print genfs path into *out buffer. + * + * Returns -1 on error. + * Returns 0 on successfully retrieving a genfs entry. + * Returns 1 on successfully retrieving the final genfs entry. + */ +int get_genfs(char *out, size_t max_size, void *policydbp, void *genfs_iterp) +{ + size_t len; + struct genfs_iter *i = static_cast<struct genfs_iter *>(genfs_iterp); + policydb_t *db = static_cast<policydb_t *>(policydbp); + + len = snprintf(out, max_size, "%s %s %s:%s:%s:s0", + i->genfs->fstype, + i->ocon->u.name, + db->p_user_val_to_name[i->ocon->context->user-1], + db->p_role_val_to_name[i->ocon->context->role-1], + db->p_type_val_to_name[i->ocon->context->type-1]); + + if (len >= max_size) { + std::cerr << "genfs path exceeds buffer size." << std::endl; + return -1; + } + + i->ocon = i->ocon->next; + if (i->ocon == NULL) { + if (i->genfs->next != NULL) { + i->genfs = i->genfs->next; + i->ocon = i->genfs->head; + } else { + return 1; + } + } + + return 0; +} + +void destroy_genfs_iter(void *genfs_iterp) +{ + struct genfs_iter *genfs_i = static_cast<struct genfs_iter *>(genfs_iterp); + free(genfs_i); +} + #define TYPE_ITER_LOOKUP 0 #define TYPE_ITER_ALLTYPES 1 #define TYPE_ITER_ALLATTRS 2 diff --git a/tests/sepolicy_tests.py b/tests/sepolicy_tests.py index 2cf4ae8148d9547ebe18c6ea72d0760cebd0c542..b09c60bc3dca1272c9c5f24c5ab0ea2fa5806e3b 100644 --- a/tests/sepolicy_tests.py +++ b/tests/sepolicy_tests.py @@ -12,13 +12,17 @@ def TestDataTypeViolations(pol): return pol.AssertPathTypesHaveAttr(["/data/"], [], "data_file_type") def TestSysfsTypeViolations(pol): - return pol.AssertPathTypesHaveAttr(["/sys/"], ["/sys/kernel/debug/", + ret = pol.AssertGenfsFilesystemTypesHaveAttr("sysfs", "sysfs_type") + ret += pol.AssertPathTypesHaveAttr(["/sys/"], ["/sys/kernel/debug/", "/sys/kernel/tracing"], "sysfs_type") + return ret def TestDebugfsTypeViolations(pol): - # TODO: this should apply to genfs_context entries as well - return pol.AssertPathTypesHaveAttr(["/sys/kernel/debug/", + ret = pol.AssertGenfsFilesystemTypesHaveAttr("debugfs", "debugfs_type") + ret += pol.AssertGenfsFilesystemTypesHaveAttr("tracefs", "debugfs_type") + ret += pol.AssertPathTypesHaveAttr(["/sys/kernel/debug/", "/sys/kernel/tracing"], [], "debugfs_type") + return ret def TestVendorTypeViolations(pol): return pol.AssertPathTypesHaveAttr(["/vendor/"], [], "vendor_file_type")