Loading libs/permission/Android.bp +27 −1 Original line number Original line Diff line number Diff line Loading @@ -7,17 +7,43 @@ package { default_applicable_licenses: ["frameworks_native_license"], default_applicable_licenses: ["frameworks_native_license"], } } aidl_interface { name: "framework-permission-aidl", unstable: true, local_include_dir: "aidl", backend: { ndk: { enabled: false } }, srcs: [ "aidl/android/content/AttributionSourceState.aidl", "aidl/android/permission/IPermissionChecker.aidl", ], } cc_library_shared { cc_library_shared { name: "libpermission", name: "libpermission", cflags: [ "-Wall", "-Wextra", "-Werror", ], srcs: [ srcs: [ "AppOpsManager.cpp", "AppOpsManager.cpp", "IAppOpsCallback.cpp", "IAppOpsCallback.cpp", "IAppOpsService.cpp", "IAppOpsService.cpp", "android/permission/PermissionChecker.cpp", ], ], export_include_dirs: ["include"], export_include_dirs: ["include"], shared_libs: [ shared_libs: [ "libutils", "libbinder", "libbinder", "libcutils", "liblog", "liblog", "libutils", ], ], static_libs: [ "framework-permission-aidl-cpp", ], export_static_lib_headers: ["framework-permission-aidl-cpp"], } } libs/permission/aidl/android/content/AttributionSourceState.aidl 0 → 100644 +40 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content; /** * Payload for the {@link AttributionSource} class needed to interoperate * with different languages. * * {@hide} */ parcelable AttributionSourceState { /** The UID that is accessing the permission protected data. */ int uid; /** The package that is accessing the permission protected data. */ @nullable @utf8InCpp String packageName; /** The attribution tag of the app accessing the permission protected data. */ @nullable @utf8InCpp String attributionTag; /** Unique token for that source. */ @nullable IBinder token; /** Permissions that should be considered revoked regardless if granted. */ @nullable @utf8InCpp String[] renouncedPermissions; /** 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; } libs/permission/aidl/android/permission/IPermissionChecker.aidl 0 → 100644 +37 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.permission; import android.content.AttributionSourceState; /** * Interface to communicate directly with the permission checker service. */ interface IPermissionChecker { const int PERMISSION_GRANTED = 0; const int PERMISSION_SOFT_DENIED = 1; const int PERMISSION_HARD_DENIED = 2; int checkPermission(String permission, in AttributionSourceState attributionSource, @nullable String message, boolean forDataDelivery, boolean startDataDelivery, boolean fromDatasource); void finishDataDelivery(String op, in AttributionSourceState attributionSource); int checkOp(int op, in AttributionSourceState attributionSource, String message, boolean forDataDelivery, boolean startDataDelivery); } libs/permission/android/permission/PermissionChecker.cpp 0 → 100644 +114 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <mutex> #include <include/android/permission/PermissionChecker.h> #include <binder/Binder.h> #include <binder/IServiceManager.h> #include <utils/SystemClock.h> #include <sys/types.h> #include <private/android_filesystem_config.h> #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "PermissionChecker" namespace android { using android::content::AttributionSourceState; PermissionChecker::PermissionChecker() { } sp<IPermissionChecker> PermissionChecker::getService() { static String16 permission_checker("permission_checker"); std::lock_guard<Mutex> scoped_lock(mLock); int64_t startTime = 0; sp<IPermissionChecker> service = mService; while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) { sp<IBinder> binder = defaultServiceManager()->checkService(permission_checker); if (binder == nullptr) { // Wait for the permission checker service to come back... if (startTime == 0) { startTime = uptimeMillis(); ALOGW("Waiting for permission checker service"); } else if ((uptimeMillis() - startTime) > 10000) { ALOGE("Waiting too long for permission checker service, giving up"); service = nullptr; break; } sleep(1); } else { mService = interface_cast<IPermissionChecker>(binder); } } return mService; } PermissionChecker::PermissionResult PermissionChecker::checkPermissionForDataDeliveryFromDatasource( const String16& permission, AttributionSourceState& attributionSource, const String16& message) { return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true, /*startDataDelivery*/ false,/*fromDatasource*/ true)); } PermissionChecker::PermissionResult PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource( const String16& permission, AttributionSourceState& attributionSource, const String16& message) { return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true, /*startDataDelivery*/ true, /*fromDatasource*/ true)); } void PermissionChecker::finishDataDelivery(const String16& op, AttributionSourceState& attributionSource) { sp<IPermissionChecker> service = getService(); if (service != nullptr) { binder::Status status = service->finishDataDelivery(op, attributionSource); 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) { sp<IPermissionChecker> service = getService(); if (service != nullptr) { int32_t result; binder::Status status = service->checkPermission(permission, attributionSource, message, forDataDelivery, startDataDelivery, fromDatasource, &result); if (status.isOk()) { return result; } ALOGE("checkPermission failed: %s", status.exceptionMessage().c_str()); } return PERMISSION_DENIED; } } // namespace android libs/permission/include/android/permission/PermissionChecker.h 0 → 100644 +136 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <android/content/AttributionSourceState.h> #include <android/permission/IPermissionChecker.h> #include <utils/threads.h> #include <optional> #ifdef __ANDROID_VNDK__ #error "This header is not visible to vendors" #endif // --------------------------------------------------------------------------- namespace android { using android::content::AttributionSourceState; using android::permission::IPermissionChecker; class PermissionChecker { public: enum PermissionResult { /** * The permission is granted. */ PERMISSION_GRANTED = IPermissionChecker::PERMISSION_GRANTED, /** * The permission is denied. Applicable only to runtime and app op permissions. * * Returned when: * - the runtime permission is granted, but the corresponding app op is denied * for runtime permissions. * - the app ops is ignored for app op permissions. * */ PERMISSION_SOFT_DENIED = IPermissionChecker::PERMISSION_SOFT_DENIED, /** * The permission is denied. * * Returned when: * - the permission is denied for non app op permissions. * - the app op is denied or app op is AppOpsManager#MODE_DEFAULT and permission is denied. */ PERMISSION_HARD_DENIED = IPermissionChecker::PERMISSION_HARD_DENIED }; PermissionChecker(); /** * 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 * * 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 point where you will deliver * the permission protected data to clients. * * @param permission The permission to check. * @param attributionSource The attribution chain to check. * @param message A message describing the reason the permission was checked. * @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); /** * 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. * * 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 point where you will deliver * the permission protected data to clients. * * @param permission The permission to check. * @param attributionSource The attribution chain to check. * @param message A message describing the reason the permission was checked. * @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); /** * Finishes an ongoing op for data access chain described by the given * attribution source. * * @param op The op to finish. * @param attributionSource The attribution chain for which to finish data delivery. */ void finishDataDelivery(const String16& op, AttributionSourceState& attributionSource); private: Mutex mLock; sp<IPermissionChecker> mService; sp<IPermissionChecker> getService(); int32_t checkPermission(const String16& permission, AttributionSourceState& attributionSource, const String16& message, bool forDataDelivery, bool startDataDelivery, bool fromDatasource); }; } // namespace android // --------------------------------------------------------------------------- Loading
libs/permission/Android.bp +27 −1 Original line number Original line Diff line number Diff line Loading @@ -7,17 +7,43 @@ package { default_applicable_licenses: ["frameworks_native_license"], default_applicable_licenses: ["frameworks_native_license"], } } aidl_interface { name: "framework-permission-aidl", unstable: true, local_include_dir: "aidl", backend: { ndk: { enabled: false } }, srcs: [ "aidl/android/content/AttributionSourceState.aidl", "aidl/android/permission/IPermissionChecker.aidl", ], } cc_library_shared { cc_library_shared { name: "libpermission", name: "libpermission", cflags: [ "-Wall", "-Wextra", "-Werror", ], srcs: [ srcs: [ "AppOpsManager.cpp", "AppOpsManager.cpp", "IAppOpsCallback.cpp", "IAppOpsCallback.cpp", "IAppOpsService.cpp", "IAppOpsService.cpp", "android/permission/PermissionChecker.cpp", ], ], export_include_dirs: ["include"], export_include_dirs: ["include"], shared_libs: [ shared_libs: [ "libutils", "libbinder", "libbinder", "libcutils", "liblog", "liblog", "libutils", ], ], static_libs: [ "framework-permission-aidl-cpp", ], export_static_lib_headers: ["framework-permission-aidl-cpp"], } }
libs/permission/aidl/android/content/AttributionSourceState.aidl 0 → 100644 +40 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content; /** * Payload for the {@link AttributionSource} class needed to interoperate * with different languages. * * {@hide} */ parcelable AttributionSourceState { /** The UID that is accessing the permission protected data. */ int uid; /** The package that is accessing the permission protected data. */ @nullable @utf8InCpp String packageName; /** The attribution tag of the app accessing the permission protected data. */ @nullable @utf8InCpp String attributionTag; /** Unique token for that source. */ @nullable IBinder token; /** Permissions that should be considered revoked regardless if granted. */ @nullable @utf8InCpp String[] renouncedPermissions; /** 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; }
libs/permission/aidl/android/permission/IPermissionChecker.aidl 0 → 100644 +37 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.permission; import android.content.AttributionSourceState; /** * Interface to communicate directly with the permission checker service. */ interface IPermissionChecker { const int PERMISSION_GRANTED = 0; const int PERMISSION_SOFT_DENIED = 1; const int PERMISSION_HARD_DENIED = 2; int checkPermission(String permission, in AttributionSourceState attributionSource, @nullable String message, boolean forDataDelivery, boolean startDataDelivery, boolean fromDatasource); void finishDataDelivery(String op, in AttributionSourceState attributionSource); int checkOp(int op, in AttributionSourceState attributionSource, String message, boolean forDataDelivery, boolean startDataDelivery); }
libs/permission/android/permission/PermissionChecker.cpp 0 → 100644 +114 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <mutex> #include <include/android/permission/PermissionChecker.h> #include <binder/Binder.h> #include <binder/IServiceManager.h> #include <utils/SystemClock.h> #include <sys/types.h> #include <private/android_filesystem_config.h> #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "PermissionChecker" namespace android { using android::content::AttributionSourceState; PermissionChecker::PermissionChecker() { } sp<IPermissionChecker> PermissionChecker::getService() { static String16 permission_checker("permission_checker"); std::lock_guard<Mutex> scoped_lock(mLock); int64_t startTime = 0; sp<IPermissionChecker> service = mService; while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) { sp<IBinder> binder = defaultServiceManager()->checkService(permission_checker); if (binder == nullptr) { // Wait for the permission checker service to come back... if (startTime == 0) { startTime = uptimeMillis(); ALOGW("Waiting for permission checker service"); } else if ((uptimeMillis() - startTime) > 10000) { ALOGE("Waiting too long for permission checker service, giving up"); service = nullptr; break; } sleep(1); } else { mService = interface_cast<IPermissionChecker>(binder); } } return mService; } PermissionChecker::PermissionResult PermissionChecker::checkPermissionForDataDeliveryFromDatasource( const String16& permission, AttributionSourceState& attributionSource, const String16& message) { return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true, /*startDataDelivery*/ false,/*fromDatasource*/ true)); } PermissionChecker::PermissionResult PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource( const String16& permission, AttributionSourceState& attributionSource, const String16& message) { return static_cast<PermissionResult>(checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true, /*startDataDelivery*/ true, /*fromDatasource*/ true)); } void PermissionChecker::finishDataDelivery(const String16& op, AttributionSourceState& attributionSource) { sp<IPermissionChecker> service = getService(); if (service != nullptr) { binder::Status status = service->finishDataDelivery(op, attributionSource); 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) { sp<IPermissionChecker> service = getService(); if (service != nullptr) { int32_t result; binder::Status status = service->checkPermission(permission, attributionSource, message, forDataDelivery, startDataDelivery, fromDatasource, &result); if (status.isOk()) { return result; } ALOGE("checkPermission failed: %s", status.exceptionMessage().c_str()); } return PERMISSION_DENIED; } } // namespace android
libs/permission/include/android/permission/PermissionChecker.h 0 → 100644 +136 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <android/content/AttributionSourceState.h> #include <android/permission/IPermissionChecker.h> #include <utils/threads.h> #include <optional> #ifdef __ANDROID_VNDK__ #error "This header is not visible to vendors" #endif // --------------------------------------------------------------------------- namespace android { using android::content::AttributionSourceState; using android::permission::IPermissionChecker; class PermissionChecker { public: enum PermissionResult { /** * The permission is granted. */ PERMISSION_GRANTED = IPermissionChecker::PERMISSION_GRANTED, /** * The permission is denied. Applicable only to runtime and app op permissions. * * Returned when: * - the runtime permission is granted, but the corresponding app op is denied * for runtime permissions. * - the app ops is ignored for app op permissions. * */ PERMISSION_SOFT_DENIED = IPermissionChecker::PERMISSION_SOFT_DENIED, /** * The permission is denied. * * Returned when: * - the permission is denied for non app op permissions. * - the app op is denied or app op is AppOpsManager#MODE_DEFAULT and permission is denied. */ PERMISSION_HARD_DENIED = IPermissionChecker::PERMISSION_HARD_DENIED }; PermissionChecker(); /** * 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 * * 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 point where you will deliver * the permission protected data to clients. * * @param permission The permission to check. * @param attributionSource The attribution chain to check. * @param message A message describing the reason the permission was checked. * @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); /** * 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. * * 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 point where you will deliver * the permission protected data to clients. * * @param permission The permission to check. * @param attributionSource The attribution chain to check. * @param message A message describing the reason the permission was checked. * @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); /** * Finishes an ongoing op for data access chain described by the given * attribution source. * * @param op The op to finish. * @param attributionSource The attribution chain for which to finish data delivery. */ void finishDataDelivery(const String16& op, AttributionSourceState& attributionSource); private: Mutex mLock; sp<IPermissionChecker> mService; sp<IPermissionChecker> getService(); int32_t checkPermission(const String16& permission, AttributionSourceState& attributionSource, const String16& message, bool forDataDelivery, bool startDataDelivery, bool fromDatasource); }; } // namespace android // ---------------------------------------------------------------------------