blob: 6c16317a8f0871baf096a909a142f343ab3f2371 [file] [log] [blame]
Austin Borger249e6592024-03-10 22:28:11 -07001/*
2 * Copyright (C) 2024 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 "AttributionAndPermissionUtils.h"
18
19#include <binder/AppOpsManager.h>
20#include <binder/PermissionController.h>
Avichal Rakesh5788fec2024-03-15 14:39:20 -070021#include <com_android_internal_camera_flags.h>
Austin Borger249e6592024-03-10 22:28:11 -070022#include <cutils/properties.h>
23#include <private/android_filesystem_config.h>
24
25#include "CameraService.h"
Austin Borger22c5c852024-03-08 13:31:36 -080026
27#include <binder/IPCThreadState.h>
28#include <hwbinder/IPCThreadState.h>
29#include <binderthreadstate/CallerUtils.h>
Austin Borger249e6592024-03-10 22:28:11 -070030
Austin Borgerce55edb2024-09-23 15:12:56 -070031namespace {
32 static const std::string kPermissionServiceName = "permission";
33} // namespace anonymous
34
Austin Borger249e6592024-03-10 22:28:11 -070035namespace android {
36
Avichal Rakesh5788fec2024-03-15 14:39:20 -070037namespace flags = com::android::internal::camera::flags;
38
Austin Borger249e6592024-03-10 22:28:11 -070039const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
40const std::string AttributionAndPermissionUtils::sManageCameraPermission(
41 "android.permission.MANAGE_CAMERA");
42const std::string AttributionAndPermissionUtils::sCameraPermission(
43 "android.permission.CAMERA");
44const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
45 "android.permission.SYSTEM_CAMERA");
46const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
47 "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
48const std::string AttributionAndPermissionUtils::sCameraPrivacyAllowlistPermission(
49 "android.permission.CAMERA_PRIVACY_ALLOWLIST");
50const std::string AttributionAndPermissionUtils::sCameraSendSystemEventsPermission(
51 "android.permission.CAMERA_SEND_SYSTEM_EVENTS");
52const std::string AttributionAndPermissionUtils::sCameraOpenCloseListenerPermission(
53 "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
54const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
55 "android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
56
Austin Borger22c5c852024-03-08 13:31:36 -080057int AttributionAndPermissionUtils::getCallingUid() {
58 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
59 return hardware::IPCThreadState::self()->getCallingUid();
60 }
61 return IPCThreadState::self()->getCallingUid();
62}
63
64int AttributionAndPermissionUtils::getCallingPid() {
65 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
66 return hardware::IPCThreadState::self()->getCallingPid();
67 }
68 return IPCThreadState::self()->getCallingPid();
69}
70
71int64_t AttributionAndPermissionUtils::clearCallingIdentity() {
72 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
73 return hardware::IPCThreadState::self()->clearCallingIdentity();
74 }
75 return IPCThreadState::self()->clearCallingIdentity();
76}
77
78void AttributionAndPermissionUtils::restoreCallingIdentity(int64_t token) {
79 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
80 hardware::IPCThreadState::self()->restoreCallingIdentity(token);
81 } else {
82 IPCThreadState::self()->restoreCallingIdentity(token);
83 }
84 return;
85}
86
Austin Borgerb01a8702024-07-22 16:20:34 -070087// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
88bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
89 int callingUid = getCallingUid();
90
91 if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
92 clientUid = callingUid;
93 } else if (!isTrustedCallingUid(callingUid)) {
94 return false;
95 }
96
97 return true;
98}
99
100// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
101bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
102 int callingUid = getCallingUid();
103 int callingPid = getCallingPid();
104
105 if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
106 clientPid = callingPid;
107 } else if (!isTrustedCallingUid(callingUid)) {
108 return false;
109 }
110
111 return true;
112}
113
Austin Borger249e6592024-03-10 22:28:11 -0700114bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(const std::string &cameraId,
115 const AttributionSourceState &attributionSource) {
116 if (isAutomotivePrivilegedClient(attributionSource.uid)) {
117 // If cameraId is empty, then it means that this check is not used for the
118 // purpose of accessing a specific camera, hence grant permission just
119 // based on uid to the automotive privileged client.
120 if (cameraId.empty())
121 return true;
122
123 auto cameraService = mCameraService.promote();
124 if (cameraService == nullptr) {
125 ALOGE("%s: CameraService unavailable.", __FUNCTION__);
126 return false;
127 }
128
129 // If this call is used for accessing a specific camera then cam_id must be provided.
130 // In that case, only pre-grants the permission for accessing the exterior system only
131 // camera.
132 return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
133 }
134
135 return false;
136}
137
138bool AttributionAndPermissionUtils::checkPermissionForPreflight(const std::string &cameraId,
139 const std::string &permission, const AttributionSourceState &attributionSource,
140 const std::string& message, int32_t attributedOpCode) {
141 if (checkAutomotivePrivilegedClient(cameraId, attributionSource)) {
142 return true;
143 }
144
Austin Borgerce55edb2024-09-23 15:12:56 -0700145 return mPermissionChecker->checkPermissionForPreflight(
146 toString16(permission), attributionSource, toString16(message),
147 attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
Austin Borger249e6592024-03-10 22:28:11 -0700148}
149
150// Can camera service trust the caller based on the calling UID?
151bool AttributionAndPermissionUtils::isTrustedCallingUid(uid_t uid) {
152 switch (uid) {
153 case AID_MEDIA: // mediaserver
154 case AID_CAMERASERVER: // cameraserver
155 case AID_RADIO: // telephony
156 return true;
157 default:
158 return false;
159 }
160}
161
162bool AttributionAndPermissionUtils::isAutomotiveDevice() {
163 // Checks the property ro.hardware.type and returns true if it is
164 // automotive.
165 char value[PROPERTY_VALUE_MAX] = {0};
166 property_get("ro.hardware.type", value, "");
167 return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
168}
169
170bool AttributionAndPermissionUtils::isHeadlessSystemUserMode() {
171 // Checks if the device is running in headless system user mode
172 // by checking the property ro.fw.mu.headless_system_user.
173 char value[PROPERTY_VALUE_MAX] = {0};
174 property_get("ro.fw.mu.headless_system_user", value, "");
175 return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
176}
177
178bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
179 // Returns false if this is not an automotive device type.
180 if (!isAutomotiveDevice())
181 return false;
182
183 // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
184 // privileged client uid used for safety critical use cases such as
185 // rear view and surround view.
186 return uid == AID_AUTOMOTIVE_EVS;
187}
188
Austin Borgerce55edb2024-09-23 15:12:56 -0700189std::string AttributionAndPermissionUtils::getPackageNameFromUid(int clientUid) const {
190 std::string packageName("");
191
192 sp<IPermissionController> permCtrl = getPermissionController();
193 if (permCtrl == nullptr) {
194 // Return empty package name and the further interaction
195 // with camera will likely fail
196 return packageName;
197 }
198
199 Vector<String16> packages;
200
201 permCtrl->getPackagesForUid(clientUid, packages);
202
203 if (packages.isEmpty()) {
204 ALOGE("No packages for calling UID %d", clientUid);
205 // Return empty package name and the further interaction
206 // with camera will likely fail
207 return packageName;
208 }
209
210 // Arbitrarily pick the first name in the list
211 packageName = toStdString(packages[0]);
212
213 return packageName;
214}
215
Austin Borger249e6592024-03-10 22:28:11 -0700216status_t AttributionAndPermissionUtils::getUidForPackage(const std::string &packageName,
217 int userId, /*inout*/uid_t& uid, int err) {
218 PermissionController pc;
219 uid = pc.getPackageUid(toString16(packageName), 0);
220 if (uid <= 0) {
221 ALOGE("Unknown package: '%s'", packageName.c_str());
222 dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
223 return BAD_VALUE;
224 }
225
226 if (userId < 0) {
227 ALOGE("Invalid user: %d", userId);
228 dprintf(err, "Invalid user: %d\n", userId);
229 return BAD_VALUE;
230 }
231
232 uid = multiuser_get_uid(userId, uid);
233 return NO_ERROR;
234}
235
236bool AttributionAndPermissionUtils::isCallerCameraServerNotDelegating() {
Austin Borger22c5c852024-03-08 13:31:36 -0800237 return (getCallingPid() == getpid());
Austin Borger249e6592024-03-10 22:28:11 -0700238}
239
240bool AttributionAndPermissionUtils::hasPermissionsForCamera(const std::string& cameraId,
241 const AttributionSourceState& attributionSource) {
242 return checkPermissionForPreflight(cameraId, sCameraPermission,
243 attributionSource, std::string(), AppOpsManager::OP_NONE);
244}
245
246bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(const std::string& cameraId,
247 const AttributionSourceState& attributionSource, bool checkCameraPermissions) {
248 bool systemCameraPermission = checkPermissionForPreflight(cameraId,
249 sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
250 return systemCameraPermission && (!checkCameraPermissions
251 || hasPermissionsForCamera(cameraId, attributionSource));
252}
253
254bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
255 const std::string& cameraId, const AttributionSourceState& attributionSource) {
256 return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
257 attributionSource, std::string(), AppOpsManager::OP_NONE);
258}
259
260bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
261 const AttributionSourceState& attributionSource) {
262 return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
263 attributionSource, std::string(), AppOpsManager::OP_NONE);
264}
265
266bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
267 const AttributionSourceState& attributionSource) {
268 return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
269 attributionSource, std::string(), AppOpsManager::OP_NONE);
270}
271
Austin Borgerce55edb2024-09-23 15:12:56 -0700272const sp<IPermissionController>& AttributionAndPermissionUtils::getPermissionController() const {
273 static const char* kPermissionControllerService = "permission";
274 static thread_local sp<IPermissionController> sPermissionController = nullptr;
275
276 if (sPermissionController == nullptr ||
277 !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
278 sp<IServiceManager> sm = defaultServiceManager();
279 sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
280 if (binder == nullptr) {
281 ALOGE("%s: Could not get permission service", __FUNCTION__);
282 sPermissionController = nullptr;
283 } else {
284 sPermissionController = interface_cast<IPermissionController>(binder);
285 }
286 }
287
288 return sPermissionController;
289}
290
Austin Borger249e6592024-03-10 22:28:11 -0700291} // namespace android