Implement SELinux access control.

This implements SELinux access control similarly
to framework servicemanager; we lookup labels in
a hwservice_contexts file, then check if the source
context has permissions to do {add, find}
operations on those particular labels. There's also
a generic "list" operation that allows for listing
services.

Note that when trying to "add" an interface, we require
the caller to be allowed to "add" the interface
*AND* all of its parents. This is because the interface
chain is provided by the client, and so can't be trusted
by hwservicemanager.

When trying to "find" an interface, we only check that
you have access to the interface you're asking for.

Bug: 34454312
Test: Marlin boots
Change-Id: Ia1d303e9fd9a4a6c8e7b7cff089a5bfda5023741
diff --git a/AccessControl.h b/AccessControl.h
new file mode 100644
index 0000000..e91de27
--- /dev/null
+++ b/AccessControl.h
@@ -0,0 +1,25 @@
+#include <string>
+
+#include <selinux/android.h>
+#include <selinux/avc.h>
+
+namespace android {
+
+class AccessControl {
+public:
+    AccessControl();
+    bool canAdd(const std::string& fqName, pid_t pid);
+    bool canGet(const std::string& fqName, pid_t pid);
+    bool canList(pid_t pid);
+private:
+    bool checkPermission(pid_t sourcePid, const char *perm, const char *interface);
+    bool checkPermission(pid_t sourcePid, const char *targetContext, const char *perm, const char *interface);
+
+    static int auditCallback(void *data, security_class_t cls, char *buf, size_t len);
+
+    char*                  mSeContext;
+    struct selabel_handle* mSeHandle;
+    union selinux_callback mSeCallbacks;
+};
+
+} // namespace android