get selinux context on add call arrival.
interfaceChain may take too long and allow for the PID
to become invalidated.
Bug: 68217907
Test: hidl's run_all_device_tests, boot + camera/YT sanity
Change-Id: Ie69d92f9006d10e7e3e4871f5760823291ed8e1f
diff --git a/AccessControl.cpp b/AccessControl.cpp
index abcb569..985feb7 100644
--- a/AccessControl.cpp
+++ b/AccessControl.cpp
@@ -18,6 +18,7 @@
};
using android::FQName;
+using Context = AccessControl::Context;
AccessControl::AccessControl() {
mSeHandle = selinux_android_hw_service_context_handle();
@@ -36,7 +37,7 @@
selinux_set_callback(SELINUX_CB_LOG, mSeCallbacks);
}
-bool AccessControl::canAdd(const std::string& fqName, pid_t pid) {
+bool AccessControl::canAdd(const std::string& fqName, const Context &context, pid_t pid) {
FQName fqIface(fqName);
if (!fqIface.isValid()) {
@@ -44,7 +45,7 @@
}
const std::string checkName = fqIface.package() + "::" + fqIface.name();
- return checkPermission(pid, kPermissionAdd, checkName.c_str());
+ return checkPermission(context, pid, kPermissionAdd, checkName.c_str());
}
bool AccessControl::canGet(const std::string& fqName, pid_t pid) {
@@ -55,36 +56,42 @@
}
const std::string checkName = fqIface.package() + "::" + fqIface.name();
- return checkPermission(pid, kPermissionGet, checkName.c_str());
+ return checkPermission(getContext(pid), pid, kPermissionGet, checkName.c_str());
}
bool AccessControl::canList(pid_t pid) {
- return checkPermission(pid, mSeContext, kPermissionList, nullptr);
+ return checkPermission(getContext(pid), pid, mSeContext, kPermissionList, nullptr);
}
-bool AccessControl::checkPermission(pid_t sourcePid, const char *targetContext,
- const char *perm, const char *interface) {
+Context AccessControl::getContext(pid_t sourcePid) {
char *sourceContext = NULL;
- bool allowed = false;
- struct audit_data ad;
if (getpidcon(sourcePid, &sourceContext) < 0) {
ALOGE("SELinux: failed to retrieve process context for pid %d", sourcePid);
+ return Context(nullptr, freecon);
+ }
+
+ return Context(sourceContext, freecon);
+}
+
+bool AccessControl::checkPermission(const Context &context, pid_t sourceAuditPid, const char *targetContext, const char *perm, const char *interface) {
+ if (context == nullptr) {
return false;
}
- ad.pid = sourcePid;
+ bool allowed = false;
+ struct audit_data ad;
+
+ ad.pid = sourceAuditPid;
ad.interfaceName = interface;
- allowed = (selinux_check_access(sourceContext, targetContext, "hwservice_manager",
+ allowed = (selinux_check_access(context.get(), targetContext, "hwservice_manager",
perm, (void *) &ad) == 0);
- freecon(sourceContext);
-
return allowed;
}
-bool AccessControl::checkPermission(pid_t sourcePid, const char *perm, const char *interface) {
+bool AccessControl::checkPermission(const Context &context, pid_t sourceAuditPid, const char *perm, const char *interface) {
char *targetContext = NULL;
bool allowed = false;
@@ -94,7 +101,7 @@
return false;
}
- allowed = checkPermission(sourcePid, targetContext, perm, interface);
+ allowed = checkPermission(context, sourceAuditPid, targetContext, perm, interface);
freecon(targetContext);