Use data delivery permission checks
The new PermissionChecker APIs check permission for a client while also
intiating an AppOp at the same time. They are also capable of checking
permissions for the full AttributionSource chain in the process.
In this change, we switch out the legacy AppOpsManager APIs for the
new PermissionChecker APIs. Some details may need to be ironed out,
particularly when it comes to prioritization of clients. This will be
handled in a future CL.
Bug: 190657833
Bug: 369841571
Test: Ran CameraPermissionTest with 10 iterations for all flag permutations
Flag: com.android.internal.camera.flags.check_full_attribution_source_chain
Change-Id: If6a777bcb9af4f7004a45a2aac35a404be8d9db1
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
index b213218..4b63704 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
@@ -132,26 +132,78 @@
return binder::Status::ok();
}
-bool AttributionAndPermissionUtils::checkPermissionForPreflight(
+PermissionChecker::PermissionResult AttributionAndPermissionUtils::checkPermission(
const std::string& cameraId, const std::string& permission,
const AttributionSourceState& attributionSource, const std::string& message,
- int32_t attributedOpCode) {
+ int32_t attributedOpCode, bool forDataDelivery, bool startDataDelivery,
+ bool checkAutomotive) {
AttributionSourceState clientAttribution = attributionSource;
if (!flags::check_full_attribution_source_chain() && !clientAttribution.next.empty()) {
clientAttribution.next.clear();
}
- if (checkAutomotivePrivilegedClient(cameraId, clientAttribution)) {
- return true;
+ if (checkAutomotive && checkAutomotivePrivilegedClient(cameraId, clientAttribution)) {
+ return PermissionChecker::PERMISSION_GRANTED;
}
- PermissionChecker::PermissionResult result = mPermissionChecker->checkPermissionForPreflight(
- toString16(permission), clientAttribution, toString16(message), attributedOpCode);
+ PermissionChecker::PermissionResult result;
+ if (forDataDelivery) {
+ if (startDataDelivery) {
+ result = mPermissionChecker->checkPermissionForStartDataDeliveryFromDatasource(
+ toString16(permission), clientAttribution, toString16(message),
+ attributedOpCode);
+ } else {
+ result = mPermissionChecker->checkPermissionForDataDeliveryFromDatasource(
+ toString16(permission), clientAttribution, toString16(message),
+ attributedOpCode);
+ }
+ } else {
+ result = mPermissionChecker->checkPermissionForPreflight(
+ toString16(permission), clientAttribution, toString16(message), attributedOpCode);
+ }
+
if (result == PermissionChecker::PERMISSION_HARD_DENIED) {
- ALOGE("%s: Permission denied for client attribution %s", __FUNCTION__,
+ ALOGI("%s (forDataDelivery %d startDataDelivery %d): Permission hard denied "
+ "for client attribution %s",
+ __FUNCTION__, forDataDelivery, startDataDelivery,
+ getAttributionString(clientAttribution).c_str());
+ } else if (result == PermissionChecker::PERMISSION_SOFT_DENIED) {
+ ALOGI("%s checkPermission (forDataDelivery %d startDataDelivery %d): Permission soft "
+ "denied "
+ "for client attribution %s",
+ __FUNCTION__, forDataDelivery, startDataDelivery,
getAttributionString(clientAttribution).c_str());
}
- return result != PermissionChecker::PERMISSION_HARD_DENIED;
+ return result;
+}
+
+bool AttributionAndPermissionUtils::checkPermissionForPreflight(
+ const std::string& cameraId, const std::string& permission,
+ const AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode) {
+ return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
+ /* forDataDelivery */ false, /* startDataDelivery */ false,
+ /* checkAutomotive */ true) != PermissionChecker::PERMISSION_HARD_DENIED;
+}
+
+bool AttributionAndPermissionUtils::checkPermissionForDataDelivery(
+ const std::string& cameraId, const std::string& permission,
+ const AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode) {
+ return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
+ /* forDataDelivery */ true, /* startDataDelivery */ false,
+ /* checkAutomotive */ false) !=
+ PermissionChecker::PERMISSION_HARD_DENIED;
+}
+
+PermissionChecker::PermissionResult
+AttributionAndPermissionUtils::checkPermissionForStartDataDelivery(
+ const std::string& cameraId, const std::string& permission,
+ const AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode) {
+ return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
+ /* forDataDelivery */ true, /* startDataDelivery */ true,
+ /* checkAutomotive */ false);
}
// Can camera service trust the caller based on the calling UID?
@@ -244,9 +296,35 @@
}
bool AttributionAndPermissionUtils::hasPermissionsForCamera(
+ const std::string& cameraId, const AttributionSourceState& attributionSource,
+ bool forDataDelivery, bool checkAutomotive) {
+ return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
+ AppOpsManager::OP_NONE, forDataDelivery, /* startDataDelivery */ false,
+ checkAutomotive) != PermissionChecker::PERMISSION_HARD_DENIED;
+}
+
+PermissionChecker::PermissionResult
+AttributionAndPermissionUtils::checkPermissionsForCameraForPreflight(
const std::string& cameraId, const AttributionSourceState& attributionSource) {
- return checkPermissionForPreflight(cameraId, sCameraPermission, attributionSource,
- std::string(), AppOpsManager::OP_NONE);
+ return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
+ AppOpsManager::OP_NONE, /* forDataDelivery */ false,
+ /* startDataDelivery */ false, /* checkAutomotive */ false);
+}
+
+PermissionChecker::PermissionResult
+AttributionAndPermissionUtils::checkPermissionsForCameraForDataDelivery(
+ const std::string& cameraId, const AttributionSourceState& attributionSource) {
+ return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
+ AppOpsManager::OP_NONE, /* forDataDelivery */ true,
+ /* startDataDelivery */ false, /* checkAutomotive */ false);
+}
+
+PermissionChecker::PermissionResult
+AttributionAndPermissionUtils::checkPermissionsForCameraForStartDataDelivery(
+ const std::string& cameraId, const AttributionSourceState& attributionSource) {
+ return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
+ AppOpsManager::OP_NONE, /* forDataDelivery */ true,
+ /* startDataDelivery */ true, /* checkAutomotive */ false);
}
bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(
@@ -277,6 +355,12 @@
attributionSource, std::string(), AppOpsManager::OP_NONE);
}
+void AttributionAndPermissionUtils::finishDataDelivery(
+ const AttributionSourceState& attributionSource) {
+ mPermissionChecker->finishDataDeliveryFromDatasource(AppOpsManager::OP_CAMERA,
+ attributionSource);
+}
+
bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(
const std::string& cameraId, const AttributionSourceState& attributionSource) {
if (isAutomotivePrivilegedClient(attributionSource.uid)) {
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
index 9ed7fa2..3361eaa 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -29,6 +29,37 @@
using content::AttributionSourceState;
using permission::PermissionChecker;
+class AttrSourceItr {
+ public:
+ using value_type = AttributionSourceState;
+ using pointer = const value_type*;
+ using reference = const value_type&;
+
+ AttrSourceItr() : mAttr(nullptr) {}
+
+ AttrSourceItr(const AttributionSourceState& attr) : mAttr(&attr) {}
+
+ reference operator*() const { return *mAttr; }
+ pointer operator->() const { return mAttr; }
+
+ AttrSourceItr& operator++() {
+ mAttr = !mAttr->next.empty() ? mAttr->next.data() : nullptr;
+ return *this;
+ }
+
+ AttrSourceItr operator++(int) {
+ AttrSourceItr tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(const AttrSourceItr& a, const AttrSourceItr& b) = default;
+
+ static AttrSourceItr end() { return AttrSourceItr{}; }
+private:
+ const AttributionSourceState * mAttr;
+};
+
/**
* Utility class consolidating methods/data for verifying permissions and the identity of the
* caller.
@@ -87,6 +118,15 @@
const std::string& permission,
const AttributionSourceState& attributionSource,
const std::string& message, int32_t attributedOpCode);
+ virtual bool checkPermissionForDataDelivery(const std::string& cameraId,
+ const std::string& permission,
+ const AttributionSourceState& attributionSource,
+ const std::string& message,
+ int32_t attributedOpCode);
+ virtual PermissionChecker::PermissionResult checkPermissionForStartDataDelivery(
+ const std::string& cameraId, const std::string& permission,
+ const AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode);
// Can camera service trust the caller based on the calling UID?
virtual bool isTrustedCallingUid(uid_t uid);
@@ -114,7 +154,14 @@
// Utils for checking specific permissions
virtual bool hasPermissionsForCamera(const std::string& cameraId,
- const AttributionSourceState& attributionSource);
+ const AttributionSourceState& attributionSource,
+ bool forDataDelivery = false, bool checkAutomotive = true);
+ virtual PermissionChecker::PermissionResult checkPermissionsForCameraForPreflight(
+ const std::string& cameraId, const AttributionSourceState& attributionSource);
+ virtual PermissionChecker::PermissionResult checkPermissionsForCameraForDataDelivery(
+ const std::string& cameraId, const AttributionSourceState& attributionSource);
+ virtual PermissionChecker::PermissionResult checkPermissionsForCameraForStartDataDelivery(
+ const std::string& cameraId, const AttributionSourceState& attributionSource);
virtual bool hasPermissionsForSystemCamera(const std::string& cameraId,
const AttributionSourceState& attributionSource,
bool checkCameraPermissions = true);
@@ -125,6 +172,8 @@
virtual bool hasPermissionsForOpenCloseListener(
const AttributionSourceState& attributionSource);
+ virtual void finishDataDelivery(const AttributionSourceState& attributionSource);
+
static const std::string sDumpPermission;
static const std::string sManageCameraPermission;
static const std::string sCameraPermission;
@@ -156,6 +205,12 @@
private:
virtual const sp<IPermissionController>& getPermissionController() const;
+ virtual PermissionChecker::PermissionResult checkPermission(
+ const std::string& cameraId, const std::string& permission,
+ const AttributionSourceState& attributionSource, const std::string& message,
+ int32_t attributedOpCode, bool forDataDelivery, bool startDataDelivery,
+ bool checkAutomotive);
+
std::unique_ptr<permission::PermissionChecker> mPermissionChecker =
std::make_unique<permission::PermissionChecker>();
};
@@ -230,12 +285,39 @@
bool hasPermissionsForCamera(const std::string& cameraId, int callingPid, int callingUid,
int32_t deviceId) const {
auto attributionSource = buildAttributionSource(callingPid, callingUid, deviceId);
- return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, attributionSource);
+ return hasPermissionsForCamera(cameraId, attributionSource);
}
bool hasPermissionsForCamera(const std::string& cameraId,
const AttributionSourceState& clientAttribution) const {
- return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, clientAttribution);
+ return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, clientAttribution,
+ /* forDataDelivery */ false,
+ /* checkAutomotive */ true);
+ }
+
+ bool hasPermissionsForCameraForDataDelivery(
+ const std::string& cameraId, const AttributionSourceState& clientAttribution) const {
+ return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, clientAttribution,
+ /* forDataDelivery */ true,
+ /* checkAutomotive */ false);
+ }
+
+ PermissionChecker::PermissionResult checkPermissionsForCameraForPreflight(
+ const std::string& cameraId, const AttributionSourceState& clientAttribution) const {
+ return mAttributionAndPermissionUtils->checkPermissionsForCameraForPreflight(
+ cameraId, clientAttribution);
+ }
+
+ PermissionChecker::PermissionResult checkPermissionsForCameraForDataDelivery(
+ const std::string& cameraId, const AttributionSourceState& clientAttribution) const {
+ return mAttributionAndPermissionUtils->checkPermissionsForCameraForDataDelivery(
+ cameraId, clientAttribution);
+ }
+
+ PermissionChecker::PermissionResult checkPermissionsForCameraForStartDataDelivery(
+ const std::string& cameraId, const AttributionSourceState& clientAttribution) const {
+ return mAttributionAndPermissionUtils->checkPermissionsForCameraForStartDataDelivery(
+ cameraId, clientAttribution);
}
bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid,
@@ -264,6 +346,10 @@
attributionSource);
}
+ void finishDataDelivery(const AttributionSourceState& attributionSource) {
+ mAttributionAndPermissionUtils->finishDataDelivery(attributionSource);
+ }
+
bool isAutomotiveDevice() const { return mAttributionAndPermissionUtils->isAutomotiveDevice(); }
bool isAutomotivePrivilegedClient(int32_t uid) const {