diff options
5 files changed, 111 insertions, 44 deletions
diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp index 3243a6b5f4..0eeca5469e 100644 --- a/libs/permission/Android.bp +++ b/libs/permission/Android.bp @@ -11,19 +11,24 @@ aidl_interface { name: "framework-permission-aidl", unstable: true, local_include_dir: "aidl", - backend: { - ndk: { - enabled: false - } - }, + host_supported: true, + vendor_available: true, + double_loadable: true, srcs: [ "aidl/android/content/AttributionSourceState.aidl", "aidl/android/permission/IPermissionChecker.aidl", ], } -cc_library_shared { +cc_library { name: "libpermission", + host_supported: true, + double_loadable: true, + target: { + darwin: { + enabled: false, + }, + }, cflags: [ "-Wall", "-Wextra", @@ -45,5 +50,7 @@ cc_library_shared { static_libs: [ "framework-permission-aidl-cpp", ], - export_static_lib_headers: ["framework-permission-aidl-cpp"], + export_static_lib_headers: [ + "framework-permission-aidl-cpp" + ], } diff --git a/libs/permission/aidl/android/content/AttributionSourceState.aidl b/libs/permission/aidl/android/content/AttributionSourceState.aidl index b6e54bf153..ed1b37dc0b 100644 --- a/libs/permission/aidl/android/content/AttributionSourceState.aidl +++ b/libs/permission/aidl/android/content/AttributionSourceState.aidl @@ -23,8 +23,10 @@ package android.content; * {@hide} */ parcelable AttributionSourceState { + /** The PID that is accessing the permission protected data. */ + int pid = -1; /** The UID that is accessing the permission protected data. */ - int uid; + int uid = -1; /** The package that is accessing the permission protected data. */ @nullable @utf8InCpp String packageName; /** The attribution tag of the app accessing the permission protected data. */ @@ -36,5 +38,5 @@ parcelable AttributionSourceState { /** The next app to receive the permission protected data. */ // TODO: We use an array as a workaround - the C++ backend doesn't // support referring to the parcelable as it expects ctor/dtor - @nullable AttributionSourceState[] next; + AttributionSourceState[] next; } diff --git a/libs/permission/aidl/android/permission/IPermissionChecker.aidl b/libs/permission/aidl/android/permission/IPermissionChecker.aidl index 1f0e32d248..d3a331e1e2 100644 --- a/libs/permission/aidl/android/permission/IPermissionChecker.aidl +++ b/libs/permission/aidl/android/permission/IPermissionChecker.aidl @@ -28,9 +28,10 @@ interface IPermissionChecker { int checkPermission(String permission, in AttributionSourceState attributionSource, @nullable String message, boolean forDataDelivery, boolean startDataDelivery, - boolean fromDatasource); + boolean fromDatasource, int attributedOp); - void finishDataDelivery(String op, in AttributionSourceState attributionSource); + void finishDataDelivery(int op, in AttributionSourceState attributionSource, + boolean fromDatasource); int checkOp(int op, in AttributionSourceState attributionSource, String message, boolean forDataDelivery, boolean startDataDelivery); diff --git a/libs/permission/android/permission/PermissionChecker.cpp b/libs/permission/android/permission/PermissionChecker.cpp index a8083ee410..008afad607 100644 --- a/libs/permission/android/permission/PermissionChecker.cpp +++ b/libs/permission/android/permission/PermissionChecker.cpp @@ -29,7 +29,7 @@ #endif #define LOG_TAG "PermissionChecker" -namespace android { +namespace android::permission { using android::content::AttributionSourceState; @@ -37,7 +37,7 @@ PermissionChecker::PermissionChecker() { } -sp<IPermissionChecker> PermissionChecker::getService() +sp<android::permission::IPermissionChecker> PermissionChecker::getService() { static String16 permission_checker("permission_checker"); @@ -59,56 +59,66 @@ sp<IPermissionChecker> PermissionChecker::getService() sleep(1); } else { mService = interface_cast<IPermissionChecker>(binder); + break; } } return mService; } -PermissionChecker::PermissionResult - PermissionChecker::checkPermissionForDataDeliveryFromDatasource( - const String16& permission, AttributionSourceState& attributionSource, - const String16& message) +PermissionChecker::PermissionResult PermissionChecker::checkPermissionForDataDeliveryFromDatasource( + const String16& permission, const AttributionSourceState& attributionSource, + const String16& message, int32_t attributedOpCode) { - return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message, - /*forDataDelivery*/ true, /*startDataDelivery*/ false,/*fromDatasource*/ true)); + return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true, + /*startDataDelivery*/ false,/*fromDatasource*/ true, attributedOpCode); } PermissionChecker::PermissionResult - PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource( - const String16& permission, AttributionSourceState& attributionSource, - const String16& message) + PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource( + const String16& permission, const AttributionSourceState& attributionSource, + const String16& message, int32_t attributedOpCode) +{ + return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true, + /*startDataDelivery*/ true, /*fromDatasource*/ true, attributedOpCode); +} + +PermissionChecker::PermissionResult PermissionChecker::checkPermissionForPreflightFromDatasource( + const String16& permission, const AttributionSourceState& attributionSource, + const String16& message, int32_t attributedOpCode) { - return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message, - /*forDataDelivery*/ true, /*startDataDelivery*/ true, /*fromDatasource*/ true)); + return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ false, + /*startDataDelivery*/ false, /*fromDatasource*/ true, attributedOpCode); } -void PermissionChecker::finishDataDelivery(const String16& op, - AttributionSourceState& attributionSource) +void PermissionChecker::finishDataDeliveryFromDatasource(int32_t op, + const AttributionSourceState& attributionSource) { sp<IPermissionChecker> service = getService(); if (service != nullptr) { - binder::Status status = service->finishDataDelivery(op, attributionSource); + binder::Status status = service->finishDataDelivery(op, attributionSource, + /*fromDatasource*/ true); if (!status.isOk()) { ALOGE("finishDataDelivery failed: %s", status.exceptionMessage().c_str()); } } } -int32_t PermissionChecker::checkPermission(const String16& permission, - AttributionSourceState& attributionSource, const String16& message, - bool forDataDelivery, bool startDataDelivery, bool fromDatasource) +PermissionChecker::PermissionResult PermissionChecker::checkPermission(const String16& permission, + const AttributionSourceState& attributionSource, const String16& message, + bool forDataDelivery, bool startDataDelivery, bool fromDatasource, + int32_t attributedOpCode) { sp<IPermissionChecker> service = getService(); if (service != nullptr) { int32_t result; binder::Status status = service->checkPermission(permission, attributionSource, message, - forDataDelivery, startDataDelivery, fromDatasource, &result); + forDataDelivery, startDataDelivery, fromDatasource, attributedOpCode, &result); if (status.isOk()) { - return result; + return static_cast<PermissionResult>(result); } ALOGE("checkPermission failed: %s", status.exceptionMessage().c_str()); } - return PERMISSION_DENIED; + return PERMISSION_HARD_DENIED; } -} // namespace android +} // namespace android::permission diff --git a/libs/permission/include/android/permission/PermissionChecker.h b/libs/permission/include/android/permission/PermissionChecker.h index 20ab51fc8a..308d7942a4 100644 --- a/libs/permission/include/android/permission/PermissionChecker.h +++ b/libs/permission/include/android/permission/PermissionChecker.h @@ -30,6 +30,8 @@ // --------------------------------------------------------------------------- namespace android { +namespace permission { + using android::content::AttributionSourceState; using android::permission::IPermissionChecker; @@ -71,7 +73,8 @@ public: * Checks whether a given data access chain described by the given attribution source * has a given permission and whether the app op that corresponds to this permission * is allowed. Call this method if you are the datasource which would not blame you for - * access to the data since you are the data. Note that the attribution source chain + * access to the data since you are the data. Use this API if you are the datasource of + * the protected state. * * NOTE: The attribution source should be for yourself with its next attribution * source being the app that would receive the data from you. @@ -82,18 +85,49 @@ public: * @param permission The permission to check. * @param attributionSource The attribution chain to check. * @param message A message describing the reason the permission was checked. + * @param attributedOpCode The op code towards which to blame the access. If this + * is a valid app op the op corresponding to the checked permission (if such) + * would only be checked to ensure it is allowed and if that succeeds the + * noting would be against the attributed op. * @return The permission check result which is either PERMISSION_GRANTED, * or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED. */ PermissionChecker::PermissionResult checkPermissionForDataDeliveryFromDatasource( - const String16& permission, AttributionSourceState& attributionSource, - const String16& message); + const String16& permission, const AttributionSourceState& attributionSource, + const String16& message, int32_t attributedOpCode); + + /** + * Checks whether a given data access chain described by the given attribution source + * has a given permission and whether the app op that corresponds to this permission + * is allowed. The app ops are not noted/started. + * + * NOTE: The attribution source should be for yourself with its next attribution + * source being the app that would receive the data from you. + * + * NOTE: Use this method only for permission checks at the preflight point where you + * will not deliver the permission protected data to clients but schedule permission + * data delivery, apps register listeners, etc. + * + * @param permission The permission to check. + * @param attributionSource The attribution chain to check. + * @param message A message describing the reason the permission was checked. + * @param attributedOpCode The op code towards which to blame the access. If this + * is a valid app op the op corresponding to the checked permission (if such) + * would only be checked to ensure it is allowed and if that succeeds the + * starting would be against the attributed op. + * @return The permission check result which is either PERMISSION_GRANTED, + * or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED. + */ + PermissionResult checkPermissionForPreflightFromDatasource( + const String16& permission, const AttributionSourceState& attributionSource, + const String16& message, int32_t attributedOpCode); /** * Checks whether a given data access chain described by the given attribution source * has a given permission and whether the app op that corresponds to this permission * is allowed. The app ops are also marked as started. This is useful for long running - * permissions like camera and microphone. + * permissions like camera and microphone. Use this API if you are the datasource of + * the protected state. * * NOTE: The attribution source should be for yourself with its next attribution * source being the app that would receive the data from you. @@ -104,32 +138,45 @@ public: * @param permission The permission to check. * @param attributionSource The attribution chain to check. * @param message A message describing the reason the permission was checked. + * @param attributedOpCode The op code towards which to blame the access. If this + * is a valid app op the op corresponding to the checked permission (if such) + * would only be checked to ensure it is allowed and if that succeeds the + * starting would be against the attributed op. * @return The permission check result which is either PERMISSION_GRANTED, * or PERMISSION_SOFT_DENIED or PERMISSION_HARD_DENIED. */ PermissionResult checkPermissionForStartDataDeliveryFromDatasource( - const String16& permission, AttributionSourceState& attributionSource, - const String16& message); + const String16& permission, const AttributionSourceState& attributionSource, + const String16& message, int32_t attributedOpCode); /** * Finishes an ongoing op for data access chain described by the given - * attribution source. + * attribution source. Use this API if you are the datasource of the protected + * state. Use this API if you are the datasource of the protected state. + * + * NOTE: The attribution source should be for yourself with its next attribution + * source being the app that would receive the data from you. * * @param op The op to finish. * @param attributionSource The attribution chain for which to finish data delivery. + * @param attributedOpCode The op code towards which to blame the access. If this + * is a valid app op it is the op that would be finished. */ - void finishDataDelivery(const String16& op, AttributionSourceState& attributionSource); + void finishDataDeliveryFromDatasource(int32_t op, + const AttributionSourceState& attributionSource); private: Mutex mLock; sp<IPermissionChecker> mService; sp<IPermissionChecker> getService(); - int32_t checkPermission(const String16& permission, AttributionSourceState& attributionSource, + PermissionResult checkPermission(const String16& permission, + const AttributionSourceState& attributionSource, const String16& message, bool forDataDelivery, bool startDataDelivery, - bool fromDatasource); + bool fromDatasource, int32_t attributedOpCode); }; +} // namespace permission } // namespace android |