Assert types labeled in genfs_contexts have correct attributes

Types in sysfs should have the sysfs_type attribute, types in
debugfs and tracefs should have the debugfs_type attribute.

TODO: Test that files in procfs have the proc_type attribute.
TODO: Assert these tests in CTS.

Bug: 74182216
Test: build - these are build-time tests.
Change-Id: Icf0ff2a26c05f94da421ba23df0b92d8eef906bf
This commit is contained in:
Jeff Vander Stoep 2018-03-21 17:27:20 -07:00
parent 370a52fee5
commit 1b8284444c
4 changed files with 128 additions and 3 deletions

View file

@ -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
}

View file

@ -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:

View file

@ -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

View file

@ -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")