blob: 4b63704d4edd3ff643f8c4368bf6b1e011bda3d7 [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
Austin Borger95a00152024-09-23 17:20:24 -070017#define LOG_TAG "AttributionAndPermissionUtils"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19
Austin Borger249e6592024-03-10 22:28:11 -070020#include "AttributionAndPermissionUtils.h"
21
22#include <binder/AppOpsManager.h>
23#include <binder/PermissionController.h>
Avichal Rakesh5788fec2024-03-15 14:39:20 -070024#include <com_android_internal_camera_flags.h>
Austin Borger249e6592024-03-10 22:28:11 -070025#include <cutils/properties.h>
26#include <private/android_filesystem_config.h>
27
28#include "CameraService.h"
Austin Borger22c5c852024-03-08 13:31:36 -080029
30#include <binder/IPCThreadState.h>
Austin Borger22c5c852024-03-08 13:31:36 -080031#include <binderthreadstate/CallerUtils.h>
Austin Borger95a00152024-09-23 17:20:24 -070032#include <hwbinder/IPCThreadState.h>
Austin Borger249e6592024-03-10 22:28:11 -070033
Austin Borgerce55edb2024-09-23 15:12:56 -070034namespace {
Austin Borger23694432024-10-07 19:28:01 -070035
36using android::content::AttributionSourceState;
37
Austin Borger95a00152024-09-23 17:20:24 -070038static const std::string kPermissionServiceName = "permission";
Austin Borger23694432024-10-07 19:28:01 -070039
40static 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 = &current->next[0];
54 } else {
55 current = nullptr;
56 }
57 }
58 return ret.str();
59}
60
Austin Borger95a00152024-09-23 17:20:24 -070061} // namespace
Austin Borgerce55edb2024-09-23 15:12:56 -070062
Austin Borger249e6592024-03-10 22:28:11 -070063namespace android {
64
Avichal Rakesh5788fec2024-03-15 14:39:20 -070065namespace flags = com::android::internal::camera::flags;
66
Austin Borger249e6592024-03-10 22:28:11 -070067const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
68const std::string AttributionAndPermissionUtils::sManageCameraPermission(
69 "android.permission.MANAGE_CAMERA");
Austin Borger95a00152024-09-23 17:20:24 -070070const std::string AttributionAndPermissionUtils::sCameraPermission("android.permission.CAMERA");
Austin Borger249e6592024-03-10 22:28:11 -070071const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
72 "android.permission.SYSTEM_CAMERA");
73const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
74 "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
75const std::string AttributionAndPermissionUtils::sCameraPrivacyAllowlistPermission(
76 "android.permission.CAMERA_PRIVACY_ALLOWLIST");
77const std::string AttributionAndPermissionUtils::sCameraSendSystemEventsPermission(
78 "android.permission.CAMERA_SEND_SYSTEM_EVENTS");
79const std::string AttributionAndPermissionUtils::sCameraOpenCloseListenerPermission(
80 "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
81const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
82 "android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
83
Austin Borger95a00152024-09-23 17:20:24 -070084int AttributionAndPermissionUtils::getCallingUid() const {
Austin Borger22c5c852024-03-08 13:31:36 -080085 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
86 return hardware::IPCThreadState::self()->getCallingUid();
87 }
88 return IPCThreadState::self()->getCallingUid();
89}
90
Austin Borger95a00152024-09-23 17:20:24 -070091int AttributionAndPermissionUtils::getCallingPid() const {
Austin Borger22c5c852024-03-08 13:31:36 -080092 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
93 return hardware::IPCThreadState::self()->getCallingPid();
94 }
95 return IPCThreadState::self()->getCallingPid();
96}
97
98int64_t AttributionAndPermissionUtils::clearCallingIdentity() {
99 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
100 return hardware::IPCThreadState::self()->clearCallingIdentity();
101 }
102 return IPCThreadState::self()->clearCallingIdentity();
103}
104
105void AttributionAndPermissionUtils::restoreCallingIdentity(int64_t token) {
106 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
107 hardware::IPCThreadState::self()->restoreCallingIdentity(token);
108 } else {
109 IPCThreadState::self()->restoreCallingIdentity(token);
110 }
111 return;
112}
113
Austin Borger95a00152024-09-23 17:20:24 -0700114binder::Status AttributionAndPermissionUtils::resolveAttributionSource(
115 /*inout*/ AttributionSourceState& resolvedAttributionSource, const std::string& methodName,
116 const std::optional<std::string>& cameraIdMaybe) {
117 // Check if we can trust clientUid
118 if (!resolveClientUid(resolvedAttributionSource.uid)) {
119 return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
120 methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
121 /* isPid= */ false);
Austin Borgerb01a8702024-07-22 16:20:34 -0700122 }
123
Austin Borger95a00152024-09-23 17:20:24 -0700124 resolveAttributionPackage(resolvedAttributionSource);
Austin Borgerb01a8702024-07-22 16:20:34 -0700125
Austin Borger95a00152024-09-23 17:20:24 -0700126 if (!resolveClientPid(resolvedAttributionSource.pid)) {
127 return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
128 methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
129 /* isPid= */ true);
Austin Borgerb01a8702024-07-22 16:20:34 -0700130 }
131
Austin Borger95a00152024-09-23 17:20:24 -0700132 return binder::Status::ok();
Austin Borgerb01a8702024-07-22 16:20:34 -0700133}
134
Austin Borgera0c61f12024-10-11 13:38:35 -0700135PermissionChecker::PermissionResult AttributionAndPermissionUtils::checkPermission(
Austin Borger95a00152024-09-23 17:20:24 -0700136 const std::string& cameraId, const std::string& permission,
137 const AttributionSourceState& attributionSource, const std::string& message,
Austin Borgera0c61f12024-10-11 13:38:35 -0700138 int32_t attributedOpCode, bool forDataDelivery, bool startDataDelivery,
139 bool checkAutomotive) {
Austin Borger23694432024-10-07 19:28:01 -0700140 AttributionSourceState clientAttribution = attributionSource;
141 if (!flags::check_full_attribution_source_chain() && !clientAttribution.next.empty()) {
142 clientAttribution.next.clear();
143 }
144
Austin Borgera0c61f12024-10-11 13:38:35 -0700145 if (checkAutomotive && checkAutomotivePrivilegedClient(cameraId, clientAttribution)) {
146 return PermissionChecker::PERMISSION_GRANTED;
Austin Borger249e6592024-03-10 22:28:11 -0700147 }
148
Austin Borgera0c61f12024-10-11 13:38:35 -0700149 PermissionChecker::PermissionResult result;
150 if (forDataDelivery) {
151 if (startDataDelivery) {
152 result = mPermissionChecker->checkPermissionForStartDataDeliveryFromDatasource(
153 toString16(permission), clientAttribution, toString16(message),
154 attributedOpCode);
155 } else {
156 result = mPermissionChecker->checkPermissionForDataDeliveryFromDatasource(
157 toString16(permission), clientAttribution, toString16(message),
158 attributedOpCode);
159 }
160 } else {
161 result = mPermissionChecker->checkPermissionForPreflight(
162 toString16(permission), clientAttribution, toString16(message), attributedOpCode);
163 }
164
Austin Borger23694432024-10-07 19:28:01 -0700165 if (result == PermissionChecker::PERMISSION_HARD_DENIED) {
Austin Borgera0c61f12024-10-11 13:38:35 -0700166 ALOGI("%s (forDataDelivery %d startDataDelivery %d): Permission hard denied "
167 "for client attribution %s",
168 __FUNCTION__, forDataDelivery, startDataDelivery,
169 getAttributionString(clientAttribution).c_str());
170 } else if (result == PermissionChecker::PERMISSION_SOFT_DENIED) {
171 ALOGI("%s checkPermission (forDataDelivery %d startDataDelivery %d): Permission soft "
172 "denied "
173 "for client attribution %s",
174 __FUNCTION__, forDataDelivery, startDataDelivery,
Austin Borger23694432024-10-07 19:28:01 -0700175 getAttributionString(clientAttribution).c_str());
176 }
Austin Borgera0c61f12024-10-11 13:38:35 -0700177 return result;
178}
179
180bool AttributionAndPermissionUtils::checkPermissionForPreflight(
181 const std::string& cameraId, const std::string& permission,
182 const AttributionSourceState& attributionSource, const std::string& message,
183 int32_t attributedOpCode) {
184 return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
185 /* forDataDelivery */ false, /* startDataDelivery */ false,
186 /* checkAutomotive */ true) != PermissionChecker::PERMISSION_HARD_DENIED;
187}
188
189bool AttributionAndPermissionUtils::checkPermissionForDataDelivery(
190 const std::string& cameraId, const std::string& permission,
191 const AttributionSourceState& attributionSource, const std::string& message,
192 int32_t attributedOpCode) {
193 return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
194 /* forDataDelivery */ true, /* startDataDelivery */ false,
195 /* checkAutomotive */ false) !=
196 PermissionChecker::PERMISSION_HARD_DENIED;
197}
198
199PermissionChecker::PermissionResult
200AttributionAndPermissionUtils::checkPermissionForStartDataDelivery(
201 const std::string& cameraId, const std::string& permission,
202 const AttributionSourceState& attributionSource, const std::string& message,
203 int32_t attributedOpCode) {
204 return checkPermission(cameraId, permission, attributionSource, message, attributedOpCode,
205 /* forDataDelivery */ true, /* startDataDelivery */ true,
206 /* checkAutomotive */ false);
Austin Borger249e6592024-03-10 22:28:11 -0700207}
208
209// Can camera service trust the caller based on the calling UID?
210bool AttributionAndPermissionUtils::isTrustedCallingUid(uid_t uid) {
211 switch (uid) {
212 case AID_MEDIA: // mediaserver
213 case AID_CAMERASERVER: // cameraserver
214 case AID_RADIO: // telephony
215 return true;
216 default:
217 return false;
218 }
219}
220
221bool AttributionAndPermissionUtils::isAutomotiveDevice() {
222 // Checks the property ro.hardware.type and returns true if it is
223 // automotive.
224 char value[PROPERTY_VALUE_MAX] = {0};
225 property_get("ro.hardware.type", value, "");
226 return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
227}
228
229bool AttributionAndPermissionUtils::isHeadlessSystemUserMode() {
230 // Checks if the device is running in headless system user mode
231 // by checking the property ro.fw.mu.headless_system_user.
232 char value[PROPERTY_VALUE_MAX] = {0};
233 property_get("ro.fw.mu.headless_system_user", value, "");
234 return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
235}
236
237bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
238 // Returns false if this is not an automotive device type.
Austin Borger95a00152024-09-23 17:20:24 -0700239 if (!isAutomotiveDevice()) return false;
Austin Borger249e6592024-03-10 22:28:11 -0700240
241 // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
242 // privileged client uid used for safety critical use cases such as
243 // rear view and surround view.
244 return uid == AID_AUTOMOTIVE_EVS;
245}
246
Austin Borgerce55edb2024-09-23 15:12:56 -0700247std::string AttributionAndPermissionUtils::getPackageNameFromUid(int clientUid) const {
248 std::string packageName("");
249
250 sp<IPermissionController> permCtrl = getPermissionController();
251 if (permCtrl == nullptr) {
252 // Return empty package name and the further interaction
253 // with camera will likely fail
254 return packageName;
255 }
256
257 Vector<String16> packages;
258
259 permCtrl->getPackagesForUid(clientUid, packages);
260
261 if (packages.isEmpty()) {
262 ALOGE("No packages for calling UID %d", clientUid);
263 // Return empty package name and the further interaction
264 // with camera will likely fail
265 return packageName;
266 }
267
268 // Arbitrarily pick the first name in the list
269 packageName = toStdString(packages[0]);
270
271 return packageName;
272}
273
Austin Borger95a00152024-09-23 17:20:24 -0700274status_t AttributionAndPermissionUtils::getUidForPackage(const std::string& packageName, int userId,
275 /*inout*/ uid_t& uid, int err) {
Austin Borger249e6592024-03-10 22:28:11 -0700276 PermissionController pc;
277 uid = pc.getPackageUid(toString16(packageName), 0);
278 if (uid <= 0) {
279 ALOGE("Unknown package: '%s'", packageName.c_str());
280 dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
281 return BAD_VALUE;
282 }
283
284 if (userId < 0) {
285 ALOGE("Invalid user: %d", userId);
286 dprintf(err, "Invalid user: %d\n", userId);
287 return BAD_VALUE;
288 }
289
290 uid = multiuser_get_uid(userId, uid);
291 return NO_ERROR;
292}
293
294bool AttributionAndPermissionUtils::isCallerCameraServerNotDelegating() {
Austin Borger22c5c852024-03-08 13:31:36 -0800295 return (getCallingPid() == getpid());
Austin Borger249e6592024-03-10 22:28:11 -0700296}
297
Austin Borger95a00152024-09-23 17:20:24 -0700298bool AttributionAndPermissionUtils::hasPermissionsForCamera(
Austin Borgera0c61f12024-10-11 13:38:35 -0700299 const std::string& cameraId, const AttributionSourceState& attributionSource,
300 bool forDataDelivery, bool checkAutomotive) {
301 return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
302 AppOpsManager::OP_NONE, forDataDelivery, /* startDataDelivery */ false,
303 checkAutomotive) != PermissionChecker::PERMISSION_HARD_DENIED;
304}
305
306PermissionChecker::PermissionResult
307AttributionAndPermissionUtils::checkPermissionsForCameraForPreflight(
Austin Borger95a00152024-09-23 17:20:24 -0700308 const std::string& cameraId, const AttributionSourceState& attributionSource) {
Austin Borgera0c61f12024-10-11 13:38:35 -0700309 return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
310 AppOpsManager::OP_NONE, /* forDataDelivery */ false,
311 /* startDataDelivery */ false, /* checkAutomotive */ false);
312}
313
314PermissionChecker::PermissionResult
315AttributionAndPermissionUtils::checkPermissionsForCameraForDataDelivery(
316 const std::string& cameraId, const AttributionSourceState& attributionSource) {
317 return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
318 AppOpsManager::OP_NONE, /* forDataDelivery */ true,
319 /* startDataDelivery */ false, /* checkAutomotive */ false);
320}
321
322PermissionChecker::PermissionResult
323AttributionAndPermissionUtils::checkPermissionsForCameraForStartDataDelivery(
324 const std::string& cameraId, const AttributionSourceState& attributionSource) {
325 return checkPermission(cameraId, sCameraPermission, attributionSource, std::string(),
326 AppOpsManager::OP_NONE, /* forDataDelivery */ true,
327 /* startDataDelivery */ true, /* checkAutomotive */ false);
Austin Borger249e6592024-03-10 22:28:11 -0700328}
329
Austin Borger95a00152024-09-23 17:20:24 -0700330bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(
331 const std::string& cameraId, const AttributionSourceState& attributionSource,
332 bool checkCameraPermissions) {
333 bool systemCameraPermission =
334 checkPermissionForPreflight(cameraId, sSystemCameraPermission, attributionSource,
335 std::string(), AppOpsManager::OP_NONE);
336 return systemCameraPermission &&
337 (!checkCameraPermissions || hasPermissionsForCamera(cameraId, attributionSource));
Austin Borger249e6592024-03-10 22:28:11 -0700338}
339
340bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
341 const std::string& cameraId, const AttributionSourceState& attributionSource) {
342 return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700343 attributionSource, std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700344}
345
346bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
347 const AttributionSourceState& attributionSource) {
348 return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700349 attributionSource, std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700350}
351
352bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
353 const AttributionSourceState& attributionSource) {
354 return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700355 attributionSource, std::string(), AppOpsManager::OP_NONE);
356}
357
Austin Borgera0c61f12024-10-11 13:38:35 -0700358void AttributionAndPermissionUtils::finishDataDelivery(
359 const AttributionSourceState& attributionSource) {
360 mPermissionChecker->finishDataDeliveryFromDatasource(AppOpsManager::OP_CAMERA,
361 attributionSource);
362}
363
Austin Borger95a00152024-09-23 17:20:24 -0700364bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(
365 const std::string& cameraId, const AttributionSourceState& attributionSource) {
366 if (isAutomotivePrivilegedClient(attributionSource.uid)) {
367 // If cameraId is empty, then it means that this check is not used for the
368 // purpose of accessing a specific camera, hence grant permission just
369 // based on uid to the automotive privileged client.
370 if (cameraId.empty()) return true;
371
372 auto cameraService = mCameraService.promote();
373 if (cameraService == nullptr) {
374 ALOGE("%s: CameraService unavailable.", __FUNCTION__);
375 return false;
376 }
377
378 // If this call is used for accessing a specific camera then cam_id must be provided.
379 // In that case, only pre-grants the permission for accessing the exterior system only
380 // camera.
381 return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
382 }
383
384 return false;
385}
386
387void AttributionAndPermissionUtils::resolveAttributionPackage(
388 AttributionSourceState& resolvedAttributionSource) {
389 if (resolvedAttributionSource.packageName.has_value() &&
390 resolvedAttributionSource.packageName->size() > 0) {
391 return;
392 }
393
394 // NDK calls don't come with package names, but we need one for various cases.
395 // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
396 // do exist. For all authentication cases, all packages under the same UID get the
397 // same permissions, so picking any associated package name is sufficient. For some
398 // other cases, this may give inaccurate names for clients in logs.
399 resolvedAttributionSource.packageName = getPackageNameFromUid(resolvedAttributionSource.uid);
400}
401
402// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
403bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
404 int callingUid = getCallingUid();
405
406 bool validUid = true;
407 if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
408 clientUid = callingUid;
409 } else {
410 validUid = isTrustedCallingUid(callingUid);
411 if (flags::use_context_attribution_source()) {
412 validUid = validUid || (clientUid == callingUid);
413 }
414 }
415
416 return validUid;
417}
418
419// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
420bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
421 int callingUid = getCallingUid();
422 int callingPid = getCallingPid();
423
424 bool validPid = true;
425 if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
426 clientPid = callingPid;
427 } else {
428 validPid = isTrustedCallingUid(callingUid);
429 if (flags::use_context_attribution_source()) {
430 validPid = validPid || (clientPid == callingPid);
431 }
432 }
433
434 return validPid;
435}
436
437binder::Status AttributionAndPermissionUtils::errorNotTrusted(
438 int clientPid, int clientUid, const std::string& methodName,
439 const std::optional<std::string>& cameraIdMaybe, const std::string& clientName,
440 bool isPid) const {
441 int callingPid = getCallingPid();
442 int callingUid = getCallingUid();
443 ALOGE("CameraService::%s X (calling PID %d, calling UID %d) rejected "
444 "(don't trust %s %d)",
445 methodName.c_str(), callingPid, callingUid, isPid ? "clientPid" : "clientUid",
446 isPid ? clientPid : clientUid);
447 return STATUS_ERROR_FMT(hardware::ICameraService::ERROR_PERMISSION_DENIED,
448 "Untrusted caller (calling PID %d, UID %d) trying to "
449 "forward camera access to camera %s for client %s (PID %d, UID %d)",
450 getCallingPid(), getCallingUid(), cameraIdMaybe.value_or("N/A").c_str(),
451 clientName.c_str(), clientPid, clientUid);
Austin Borger249e6592024-03-10 22:28:11 -0700452}
453
Austin Borgerce55edb2024-09-23 15:12:56 -0700454const sp<IPermissionController>& AttributionAndPermissionUtils::getPermissionController() const {
455 static const char* kPermissionControllerService = "permission";
456 static thread_local sp<IPermissionController> sPermissionController = nullptr;
457
458 if (sPermissionController == nullptr ||
Austin Borger95a00152024-09-23 17:20:24 -0700459 !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
Austin Borgerce55edb2024-09-23 15:12:56 -0700460 sp<IServiceManager> sm = defaultServiceManager();
461 sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
462 if (binder == nullptr) {
463 ALOGE("%s: Could not get permission service", __FUNCTION__);
464 sPermissionController = nullptr;
465 } else {
466 sPermissionController = interface_cast<IPermissionController>(binder);
467 }
468 }
469
470 return sPermissionController;
471}
472
Austin Borger249e6592024-03-10 22:28:11 -0700473} // namespace android