Loading libs/permission/Android.bp +14 −7 Original line number Diff line number Diff line Loading @@ -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", Loading @@ -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" ], } libs/permission/aidl/android/content/AttributionSourceState.aidl +4 −2 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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; } libs/permission/aidl/android/permission/IPermissionChecker.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -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); Loading libs/permission/android/permission/PermissionChecker.cpp +33 −23 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ #endif #define LOG_TAG "PermissionChecker" namespace android { namespace android::permission { using android::content::AttributionSourceState; Loading @@ -37,7 +37,7 @@ PermissionChecker::PermissionChecker() { } sp<IPermissionChecker> PermissionChecker::getService() sp<android::permission::IPermissionChecker> PermissionChecker::getService() { static String16 permission_checker("permission_checker"); Loading @@ -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) 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 libs/permission/include/android/permission/PermissionChecker.h +57 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ // --------------------------------------------------------------------------- namespace android { namespace permission { using android::content::AttributionSourceState; using android::permission::IPermissionChecker; Loading Loading @@ -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. Loading @@ -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. Loading @@ -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 Loading Loading
libs/permission/Android.bp +14 −7 Original line number Diff line number Diff line Loading @@ -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", Loading @@ -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" ], }
libs/permission/aidl/android/content/AttributionSourceState.aidl +4 −2 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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; }
libs/permission/aidl/android/permission/IPermissionChecker.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -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); Loading
libs/permission/android/permission/PermissionChecker.cpp +33 −23 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ #endif #define LOG_TAG "PermissionChecker" namespace android { namespace android::permission { using android::content::AttributionSourceState; Loading @@ -37,7 +37,7 @@ PermissionChecker::PermissionChecker() { } sp<IPermissionChecker> PermissionChecker::getService() sp<android::permission::IPermissionChecker> PermissionChecker::getService() { static String16 permission_checker("permission_checker"); Loading @@ -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) 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
libs/permission/include/android/permission/PermissionChecker.h +57 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ // --------------------------------------------------------------------------- namespace android { namespace permission { using android::content::AttributionSourceState; using android::permission::IPermissionChecker; Loading Loading @@ -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. Loading @@ -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. Loading @@ -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 Loading