1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <mutex>
18 #include <include/android/permission/PermissionChecker.h>
19 #include <binder/Binder.h>
20 #include <binder/IServiceManager.h>
21
22 #include <utils/SystemClock.h>
23
24 #include <sys/types.h>
25 #include <private/android_filesystem_config.h>
26
27 #ifdef LOG_TAG
28 #undef LOG_TAG
29 #endif
30 #define LOG_TAG "PermissionChecker"
31
32 namespace android::permission {
33
34 using android::content::AttributionSourceState;
35
PermissionChecker()36 PermissionChecker::PermissionChecker()
37 {
38 }
39
getService()40 sp<android::permission::IPermissionChecker> PermissionChecker::getService()
41 {
42 static String16 permission_checker("permission_checker");
43
44 std::lock_guard<Mutex> scoped_lock(mLock);
45 int64_t startTime = 0;
46 sp<IPermissionChecker> service = mService;
47 while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
48 sp<IBinder> binder = defaultServiceManager()->checkService(permission_checker);
49 if (binder == nullptr) {
50 // Wait for the permission checker service to come back...
51 if (startTime == 0) {
52 startTime = uptimeMillis();
53 ALOGW("Waiting for permission checker service");
54 } else if ((uptimeMillis() - startTime) > 10000) {
55 ALOGE("Waiting too long for permission checker service, giving up");
56 service = nullptr;
57 break;
58 }
59 sleep(1);
60 } else {
61 mService = interface_cast<IPermissionChecker>(binder);
62 break;
63 }
64 }
65 return mService;
66 }
67
checkPermissionForDataDeliveryFromDatasource(const String16 & permission,const AttributionSourceState & attributionSource,const String16 & message,int32_t attributedOpCode)68 PermissionChecker::PermissionResult PermissionChecker::checkPermissionForDataDeliveryFromDatasource(
69 const String16& permission, const AttributionSourceState& attributionSource,
70 const String16& message, int32_t attributedOpCode)
71 {
72 return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true,
73 /*startDataDelivery*/ false,/*fromDatasource*/ true, attributedOpCode);
74 }
75
76 PermissionChecker::PermissionResult
checkPermissionForStartDataDeliveryFromDatasource(const String16 & permission,const AttributionSourceState & attributionSource,const String16 & message,int32_t attributedOpCode)77 PermissionChecker::checkPermissionForStartDataDeliveryFromDatasource(
78 const String16& permission, const AttributionSourceState& attributionSource,
79 const String16& message, int32_t attributedOpCode)
80 {
81 return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ true,
82 /*startDataDelivery*/ true, /*fromDatasource*/ true, attributedOpCode);
83 }
84
checkPermissionForPreflight(const String16 & permission,const AttributionSourceState & attributionSource,const String16 & message,int32_t attributedOpCode)85 PermissionChecker::PermissionResult PermissionChecker::checkPermissionForPreflight(
86 const String16& permission, const AttributionSourceState& attributionSource,
87 const String16& message, int32_t attributedOpCode)
88 {
89 return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ false,
90 /*startDataDelivery*/ false, /*fromDatasource*/ false, attributedOpCode);
91 }
92
checkPermissionForPreflightFromDatasource(const String16 & permission,const AttributionSourceState & attributionSource,const String16 & message,int32_t attributedOpCode)93 PermissionChecker::PermissionResult PermissionChecker::checkPermissionForPreflightFromDatasource(
94 const String16& permission, const AttributionSourceState& attributionSource,
95 const String16& message, int32_t attributedOpCode)
96 {
97 return checkPermission(permission, attributionSource, message, /*forDataDelivery*/ false,
98 /*startDataDelivery*/ false, /*fromDatasource*/ true, attributedOpCode);
99 }
100
finishDataDeliveryFromDatasource(int32_t op,const AttributionSourceState & attributionSource)101 void PermissionChecker::finishDataDeliveryFromDatasource(int32_t op,
102 const AttributionSourceState& attributionSource)
103 {
104 sp<IPermissionChecker> service = getService();
105 if (service != nullptr) {
106 binder::Status status = service->finishDataDelivery(op, attributionSource,
107 /*fromDatasource*/ true);
108 if (!status.isOk()) {
109 ALOGE("finishDataDelivery failed: %s", status.exceptionMessage().c_str());
110 }
111 }
112 }
113
checkPermission(const String16 & permission,const AttributionSourceState & attributionSource,const String16 & message,bool forDataDelivery,bool startDataDelivery,bool fromDatasource,int32_t attributedOpCode)114 PermissionChecker::PermissionResult PermissionChecker::checkPermission(const String16& permission,
115 const AttributionSourceState& attributionSource, const String16& message,
116 bool forDataDelivery, bool startDataDelivery, bool fromDatasource,
117 int32_t attributedOpCode)
118 {
119 sp<IPermissionChecker> service = getService();
120 if (service != nullptr) {
121 int32_t result;
122 binder::Status status = service->checkPermission(permission, attributionSource, message,
123 forDataDelivery, startDataDelivery, fromDatasource, attributedOpCode, &result);
124 if (status.isOk()) {
125 return static_cast<PermissionResult>(result);
126 }
127 ALOGE("checkPermission failed: %s", status.exceptionMessage().c_str());
128 }
129 return PERMISSION_HARD_DENIED;
130 }
131
132 } // namespace android::permission
133