1 /*
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 #define LOG_TAG "AttributionAndPermissionUtils"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19
20 #include "AttributionAndPermissionUtils.h"
21
22 #include <binder/AppOpsManager.h>
23 #include <binder/PermissionController.h>
24 #include <com_android_internal_camera_flags.h>
25 #include <cutils/properties.h>
26 #include <private/android_filesystem_config.h>
27
28 #include "CameraService.h"
29
30 #include <binder/IPCThreadState.h>
31 #include <binderthreadstate/CallerUtils.h>
32 #include <hwbinder/IPCThreadState.h>
33
34 namespace {
35
36 using android::content::AttributionSourceState;
37
38 static const std::string kPermissionServiceName = "permission";
39
getAttributionString(const AttributionSourceState & attributionSource)40 static std::string getAttributionString(const AttributionSourceState& attributionSource) {
41 std::ostringstream ret;
42 const AttributionSourceState* current = &attributionSource;
43 while (current != nullptr) {
44 if (current != &attributionSource) {
45 ret << ", ";
46 }
47
48 ret << "[uid " << current->uid << ", pid " << current->pid;
49 ret << ", packageName \"" << current->packageName.value_or("<unknown>");
50 ret << "\"]";
51
52 if (!current->next.empty()) {
53 current = ¤t->next[0];
54 } else {
55 current = nullptr;
56 }
57 }
58 return ret.str();
59 }
60
getAppOpsMessage(const std::string & cameraId)61 static std::string getAppOpsMessage(const std::string& cameraId) {
62 return cameraId.empty() ? std::string() : std::string("start camera ") + cameraId;
63 }
64
65 } // namespace
66
67 namespace android {
68
69 namespace flags = com::android::internal::camera::flags;
70
71 const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
72 const std::string AttributionAndPermissionUtils::sManageCameraPermission(
73 "android.permission.MANAGE_CAMERA");
74 const std::string AttributionAndPermissionUtils::sCameraPermission("android.permission.CAMERA");
75 const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
76 "android.permission.SYSTEM_CAMERA");
77 const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
78 "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
79 const std::string AttributionAndPermissionUtils::sCameraPrivacyAllowlistPermission(
80 "android.permission.CAMERA_PRIVACY_ALLOWLIST");
81 const std::string AttributionAndPermissionUtils::sCameraSendSystemEventsPermission(
82 "android.permission.CAMERA_SEND_SYSTEM_EVENTS");
83 const std::string AttributionAndPermissionUtils::sCameraOpenCloseListenerPermission(
84 "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
85 const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
86 "android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
87
getCallingUid() const88 int AttributionAndPermissionUtils::getCallingUid() const {
89 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
90 return hardware::IPCThreadState::self()->getCallingUid();
91 }
92 return IPCThreadState::self()->getCallingUid();
93 }
94
getCallingPid() const95 int AttributionAndPermissionUtils::getCallingPid() const {
96 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
97 return hardware::IPCThreadState::self()->getCallingPid();
98 }
99 return IPCThreadState::self()->getCallingPid();
100 }
101
clearCallingIdentity()102 int64_t AttributionAndPermissionUtils::clearCallingIdentity() {
103 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
104 return hardware::IPCThreadState::self()->clearCallingIdentity();
105 }
106 return IPCThreadState::self()->clearCallingIdentity();
107 }
108
restoreCallingIdentity(int64_t token)109 void AttributionAndPermissionUtils::restoreCallingIdentity(int64_t token) {
110 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
111 hardware::IPCThreadState::self()->restoreCallingIdentity(token);
112 } else {
113 IPCThreadState::self()->restoreCallingIdentity(token);
114 }
115 return;
116 }
117
resolveAttributionSource(AttributionSourceState & resolvedAttributionSource,const std::string & methodName,const std::optional<std::string> & cameraIdMaybe)118 binder::Status AttributionAndPermissionUtils::resolveAttributionSource(
119 /*inout*/ AttributionSourceState& resolvedAttributionSource, const std::string& methodName,
120 const std::optional<std::string>& cameraIdMaybe) {
121 // Check if we can trust clientUid
122 if (!resolveClientUid(resolvedAttributionSource.uid)) {
123 return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
124 methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
125 /* isPid= */ false);
126 }
127
128 resolveAttributionPackage(resolvedAttributionSource);
129
130 if (!resolveClientPid(resolvedAttributionSource.pid)) {
131 return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
132 methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
133 /* isPid= */ true);
134 }
135
136 return binder::Status::ok();
137 }
138
checkPermission(const std::string & cameraId,const std::string & permission,const AttributionSourceState & attributionSource,const std::string & message,int32_t attributedOpCode,bool forDataDelivery,bool startDataDelivery,bool checkAutomotive)139 PermissionChecker::PermissionResult AttributionAndPermissionUtils::checkPermission(
140 const std::string& cameraId, const std::string& permission,
141 const AttributionSourceState& attributionSource, const std::string& message,
142 int32_t attributedOpCode, bool forDataDelivery, bool startDataDelivery,
143 bool checkAutomotive) {
144 AttributionSourceState clientAttribution = attributionSource;
145 if (!flags::data_delivery_permission_checks() && !clientAttribution.next.empty()) {
146 clientAttribution.next.clear();
147 }
148
149 if (checkAutomotive && checkAutomotivePrivilegedClient(cameraId, clientAttribution)) {
150 return PermissionChecker::PERMISSION_GRANTED;
151 }
152
153 PermissionChecker::PermissionResult result;
154 if (forDataDelivery) {
155 if (startDataDelivery) {
156 result = mPermissionChecker->checkPermissionForStartDataDeliveryFromDatasource(
157 toString16(permission), clientAttribution, toString16(message),
158 attributedOpCode);
159 } else {
160 result = mPermissionChecker->checkPermissionForDataDeliveryFromDatasource(
161 toString16(permission), clientAttribution, toString16(message),
162 attributedOpCode);
163 }
164 } else {
165 result = mPermissionChecker->checkPermissionForPreflight(
166 toString16(permission), clientAttribution, toString16(message), attributedOpCode);
167 }
168
169 if (result == PermissionChecker::PERMISSION_HARD_DENIED) {
170 ALOGI("%s (forDataDelivery %d startDataDelivery %d): Permission hard denied "
171 "for client attribution %s",
172 __FUNCTION__, forDataDelivery, startDataDelivery,
173 getAttributionString(clientAttribution).c_str());
174 } else if (result == PermissionChecker::PERMISSION_SOFT_DENIED) {
175 ALOGI("%s checkPermission (forDataDelivery %d startDataDelivery %d): Permission soft "
176 "denied "
177 "for client attribution %s",
178 __FUNCTION__, forDataDelivery, startDataDelivery,
179 getAttributionString(clientAttribution).c_str());
180 }
181 return result;
182 }
183
checkPermissionForPreflight(const std::string & cameraId,const std::string & permission,const AttributionSourceState & attributionSource,const std::string & message,int32_t attributedOpCode)184 bool AttributionAndPermissionUtils::checkPermissionForPreflight(
185 const std::string& cameraId, const std::string& permission,
186 const AttributionSourceState& attributionSource, const std::string& message,
187 int32_t attributedOpCode) {
188 return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
189 /* forDataDelivery */ false, /* startDataDelivery */ false,
190 /* checkAutomotive */ true) != PermissionChecker::PERMISSION_HARD_DENIED;
191 }
192
checkPermissionForDataDelivery(const std::string & cameraId,const std::string & permission,const AttributionSourceState & attributionSource,const std::string & message,int32_t attributedOpCode)193 bool AttributionAndPermissionUtils::checkPermissionForDataDelivery(
194 const std::string& cameraId, const std::string& permission,
195 const AttributionSourceState& attributionSource, const std::string& message,
196 int32_t attributedOpCode) {
197 return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
198 /* forDataDelivery */ true, /* startDataDelivery */ false,
199 /* checkAutomotive */ false) !=
200 PermissionChecker::PERMISSION_HARD_DENIED;
201 }
202
203 PermissionChecker::PermissionResult
checkPermissionForStartDataDelivery(const std::string & cameraId,const std::string & permission,const AttributionSourceState & attributionSource,const std::string & message,int32_t attributedOpCode)204 AttributionAndPermissionUtils::checkPermissionForStartDataDelivery(
205 const std::string& cameraId, const std::string& permission,
206 const AttributionSourceState& attributionSource, const std::string& message,
207 int32_t attributedOpCode) {
208 return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
209 /* forDataDelivery */ true, /* startDataDelivery */ true,
210 /* checkAutomotive */ false);
211 }
212
213 // Can camera service trust the caller based on the calling UID?
isTrustedCallingUid(uid_t uid)214 bool AttributionAndPermissionUtils::isTrustedCallingUid(uid_t uid) {
215 switch (uid) {
216 case AID_MEDIA: // mediaserver
217 case AID_CAMERASERVER: // cameraserver
218 case AID_RADIO: // telephony
219 return true;
220 default:
221 return false;
222 }
223 }
224
isAutomotiveDevice()225 bool AttributionAndPermissionUtils::isAutomotiveDevice() {
226 // Checks the property ro.hardware.type and returns true if it is
227 // automotive.
228 char value[PROPERTY_VALUE_MAX] = {0};
229 property_get("ro.hardware.type", value, "");
230 return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
231 }
232
isHeadlessSystemUserMode()233 bool AttributionAndPermissionUtils::isHeadlessSystemUserMode() {
234 // Checks if the device is running in headless system user mode
235 // by checking the property ro.fw.mu.headless_system_user.
236 char value[PROPERTY_VALUE_MAX] = {0};
237 property_get("ro.fw.mu.headless_system_user", value, "");
238 return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
239 }
240
isAutomotivePrivilegedClient(int32_t uid)241 bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
242 // Returns false if this is not an automotive device type.
243 if (!isAutomotiveDevice()) return false;
244
245 // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
246 // privileged client uid used for safety critical use cases such as
247 // rear view and surround view.
248 return uid == AID_AUTOMOTIVE_EVS;
249 }
250
getPackageNameFromUid(int clientUid) const251 std::string AttributionAndPermissionUtils::getPackageNameFromUid(int clientUid) const {
252 std::string packageName("");
253
254 sp<IPermissionController> permCtrl = getPermissionController();
255 if (permCtrl == nullptr) {
256 // Return empty package name and the further interaction
257 // with camera will likely fail
258 return packageName;
259 }
260
261 Vector<String16> packages;
262
263 permCtrl->getPackagesForUid(clientUid, packages);
264
265 if (packages.isEmpty()) {
266 ALOGE("No packages for calling UID %d", clientUid);
267 // Return empty package name and the further interaction
268 // with camera will likely fail
269 return packageName;
270 }
271
272 // Arbitrarily pick the first name in the list
273 packageName = toStdString(packages[0]);
274
275 return packageName;
276 }
277
getUidForPackage(const std::string & packageName,int userId,uid_t & uid,int err)278 status_t AttributionAndPermissionUtils::getUidForPackage(const std::string& packageName, int userId,
279 /*inout*/ uid_t& uid, int err) {
280 PermissionController pc;
281 uid = pc.getPackageUid(toString16(packageName), 0);
282 if (uid <= 0) {
283 ALOGE("Unknown package: '%s'", packageName.c_str());
284 dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
285 return BAD_VALUE;
286 }
287
288 if (userId < 0) {
289 ALOGE("Invalid user: %d", userId);
290 dprintf(err, "Invalid user: %d\n", userId);
291 return BAD_VALUE;
292 }
293
294 uid = multiuser_get_uid(userId, uid);
295 return NO_ERROR;
296 }
297
isCallerCameraServerNotDelegating()298 bool AttributionAndPermissionUtils::isCallerCameraServerNotDelegating() {
299 return (getCallingPid() == getpid());
300 }
301
hasPermissionsForCamera(const std::string & cameraId,const AttributionSourceState & attributionSource,bool forDataDelivery,bool checkAutomotive)302 bool AttributionAndPermissionUtils::hasPermissionsForCamera(
303 const std::string& cameraId, const AttributionSourceState& attributionSource,
304 bool forDataDelivery, bool checkAutomotive) {
305 return checkPermission(cameraId, sCameraPermission, attributionSource,
306 getAppOpsMessage(cameraId), AppOpsManager::OP_NONE, forDataDelivery,
307 /* startDataDelivery */ false, checkAutomotive)
308 != PermissionChecker::PERMISSION_HARD_DENIED;
309 }
310
311 PermissionChecker::PermissionResult
checkPermissionsForCameraForPreflight(const std::string & cameraId,const AttributionSourceState & attributionSource)312 AttributionAndPermissionUtils::checkPermissionsForCameraForPreflight(
313 const std::string& cameraId, const AttributionSourceState& attributionSource) {
314 return checkPermission(cameraId, sCameraPermission, attributionSource,
315 getAppOpsMessage(cameraId), AppOpsManager::OP_NONE,
316 /* forDataDelivery */ false, /* startDataDelivery */ false,
317 /* checkAutomotive */ false);
318 }
319
320 PermissionChecker::PermissionResult
checkPermissionsForCameraForDataDelivery(const std::string & cameraId,const AttributionSourceState & attributionSource)321 AttributionAndPermissionUtils::checkPermissionsForCameraForDataDelivery(
322 const std::string& cameraId, const AttributionSourceState& attributionSource) {
323 return checkPermission(cameraId, sCameraPermission, attributionSource,
324 getAppOpsMessage(cameraId), AppOpsManager::OP_NONE,
325 /* forDataDelivery */ true, /* startDataDelivery */ false,
326 /* checkAutomotive */ false);
327 }
328
329 PermissionChecker::PermissionResult
checkPermissionsForCameraForStartDataDelivery(const std::string & cameraId,const AttributionSourceState & attributionSource)330 AttributionAndPermissionUtils::checkPermissionsForCameraForStartDataDelivery(
331 const std::string& cameraId, const AttributionSourceState& attributionSource) {
332 return checkPermission(cameraId, sCameraPermission, attributionSource,
333 getAppOpsMessage(cameraId), AppOpsManager::OP_NONE,
334 /* forDataDelivery */ true, /* startDataDelivery */ true,
335 /* checkAutomotive */ false);
336 }
337
hasPermissionsForSystemCamera(const std::string & cameraId,const AttributionSourceState & attributionSource,bool checkCameraPermissions)338 bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(
339 const std::string& cameraId, const AttributionSourceState& attributionSource,
340 bool checkCameraPermissions) {
341 bool systemCameraPermission =
342 checkPermissionForPreflight(cameraId, sSystemCameraPermission, attributionSource,
343 std::string(), AppOpsManager::OP_NONE);
344 return systemCameraPermission &&
345 (!checkCameraPermissions || hasPermissionsForCamera(cameraId, attributionSource));
346 }
347
hasPermissionsForCameraHeadlessSystemUser(const std::string & cameraId,const AttributionSourceState & attributionSource)348 bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
349 const std::string& cameraId, const AttributionSourceState& attributionSource) {
350 return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
351 attributionSource, std::string(), AppOpsManager::OP_NONE);
352 }
353
hasPermissionsForCameraPrivacyAllowlist(const AttributionSourceState & attributionSource)354 bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
355 const AttributionSourceState& attributionSource) {
356 return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
357 attributionSource, std::string(), AppOpsManager::OP_NONE);
358 }
359
hasPermissionsForOpenCloseListener(const AttributionSourceState & attributionSource)360 bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
361 const AttributionSourceState& attributionSource) {
362 return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
363 attributionSource, std::string(), AppOpsManager::OP_NONE);
364 }
365
finishDataDelivery(const AttributionSourceState & attributionSource)366 void AttributionAndPermissionUtils::finishDataDelivery(
367 const AttributionSourceState& attributionSource) {
368 mPermissionChecker->finishDataDeliveryFromDatasource(AppOpsManager::OP_CAMERA,
369 attributionSource);
370 }
371
checkAutomotivePrivilegedClient(const std::string & cameraId,const AttributionSourceState & attributionSource)372 bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(
373 const std::string& cameraId, const AttributionSourceState& attributionSource) {
374 if (isAutomotivePrivilegedClient(attributionSource.uid)) {
375 // If cameraId is empty, then it means that this check is not used for the
376 // purpose of accessing a specific camera, hence grant permission just
377 // based on uid to the automotive privileged client.
378 if (cameraId.empty()) return true;
379
380 auto cameraService = mCameraService.promote();
381 if (cameraService == nullptr) {
382 ALOGE("%s: CameraService unavailable.", __FUNCTION__);
383 return false;
384 }
385
386 // If this call is used for accessing a specific camera then cam_id must be provided.
387 // In that case, only pre-grants the permission for accessing the exterior system only
388 // camera.
389 return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
390 }
391
392 return false;
393 }
394
resolveAttributionPackage(AttributionSourceState & resolvedAttributionSource)395 void AttributionAndPermissionUtils::resolveAttributionPackage(
396 AttributionSourceState& resolvedAttributionSource) {
397 if (resolvedAttributionSource.packageName.has_value() &&
398 resolvedAttributionSource.packageName->size() > 0) {
399 return;
400 }
401
402 // NDK calls don't come with package names, but we need one for various cases.
403 // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
404 // do exist. For all authentication cases, all packages under the same UID get the
405 // same permissions, so picking any associated package name is sufficient. For some
406 // other cases, this may give inaccurate names for clients in logs.
407 resolvedAttributionSource.packageName = getPackageNameFromUid(resolvedAttributionSource.uid);
408 }
409
410 // TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
resolveClientUid(int & clientUid)411 bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
412 int callingUid = getCallingUid();
413
414 bool validUid = true;
415 if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
416 clientUid = callingUid;
417 } else {
418 validUid = isTrustedCallingUid(callingUid);
419 if (flags::data_delivery_permission_checks()) {
420 validUid = validUid || (clientUid == callingUid);
421 }
422 }
423
424 return validUid;
425 }
426
427 // TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
resolveClientPid(int & clientPid)428 bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
429 int callingUid = getCallingUid();
430 int callingPid = getCallingPid();
431
432 bool validPid = true;
433 if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
434 clientPid = callingPid;
435 } else {
436 validPid = isTrustedCallingUid(callingUid);
437 if (flags::data_delivery_permission_checks()) {
438 validPid = validPid || (clientPid == callingPid);
439 }
440 }
441
442 return validPid;
443 }
444
errorNotTrusted(int clientPid,int clientUid,const std::string & methodName,const std::optional<std::string> & cameraIdMaybe,const std::string & clientName,bool isPid) const445 binder::Status AttributionAndPermissionUtils::errorNotTrusted(
446 int clientPid, int clientUid, const std::string& methodName,
447 const std::optional<std::string>& cameraIdMaybe, const std::string& clientName,
448 bool isPid) const {
449 int callingPid = getCallingPid();
450 int callingUid = getCallingUid();
451 ALOGE("CameraService::%s X (calling PID %d, calling UID %d) rejected "
452 "(don't trust %s %d)",
453 methodName.c_str(), callingPid, callingUid, isPid ? "clientPid" : "clientUid",
454 isPid ? clientPid : clientUid);
455 return STATUS_ERROR_FMT(hardware::ICameraService::ERROR_PERMISSION_DENIED,
456 "Untrusted caller (calling PID %d, UID %d) trying to "
457 "forward camera access to camera %s for client %s (PID %d, UID %d)",
458 getCallingPid(), getCallingUid(), cameraIdMaybe.value_or("N/A").c_str(),
459 clientName.c_str(), clientPid, clientUid);
460 }
461
getPermissionController() const462 const sp<IPermissionController>& AttributionAndPermissionUtils::getPermissionController() const {
463 static const char* kPermissionControllerService = "permission";
464 static thread_local sp<IPermissionController> sPermissionController = nullptr;
465
466 if (sPermissionController == nullptr ||
467 !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
468 sp<IServiceManager> sm = defaultServiceManager();
469 sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
470 if (binder == nullptr) {
471 ALOGE("%s: Could not get permission service", __FUNCTION__);
472 sPermissionController = nullptr;
473 } else {
474 sPermissionController = interface_cast<IPermissionController>(binder);
475 }
476 }
477
478 return sPermissionController;
479 }
480
481 } // namespace android
482