blob: b21321878e8c6ef5bcc775083632e09de2cd6a9f [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 Borger95a00152024-09-23 17:20:24 -0700135bool AttributionAndPermissionUtils::checkPermissionForPreflight(
136 const std::string& cameraId, const std::string& permission,
137 const AttributionSourceState& attributionSource, const std::string& message,
138 int32_t attributedOpCode) {
Austin Borger23694432024-10-07 19:28:01 -0700139 AttributionSourceState clientAttribution = attributionSource;
140 if (!flags::check_full_attribution_source_chain() && !clientAttribution.next.empty()) {
141 clientAttribution.next.clear();
142 }
143
144 if (checkAutomotivePrivilegedClient(cameraId, clientAttribution)) {
Austin Borger249e6592024-03-10 22:28:11 -0700145 return true;
146 }
147
Austin Borger23694432024-10-07 19:28:01 -0700148 PermissionChecker::PermissionResult result = mPermissionChecker->checkPermissionForPreflight(
149 toString16(permission), clientAttribution, toString16(message), attributedOpCode);
150 if (result == PermissionChecker::PERMISSION_HARD_DENIED) {
151 ALOGE("%s: Permission denied for client attribution %s", __FUNCTION__,
152 getAttributionString(clientAttribution).c_str());
153 }
154 return result != PermissionChecker::PERMISSION_HARD_DENIED;
Austin Borger249e6592024-03-10 22:28:11 -0700155}
156
157// Can camera service trust the caller based on the calling UID?
158bool AttributionAndPermissionUtils::isTrustedCallingUid(uid_t uid) {
159 switch (uid) {
160 case AID_MEDIA: // mediaserver
161 case AID_CAMERASERVER: // cameraserver
162 case AID_RADIO: // telephony
163 return true;
164 default:
165 return false;
166 }
167}
168
169bool AttributionAndPermissionUtils::isAutomotiveDevice() {
170 // Checks the property ro.hardware.type and returns true if it is
171 // automotive.
172 char value[PROPERTY_VALUE_MAX] = {0};
173 property_get("ro.hardware.type", value, "");
174 return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
175}
176
177bool AttributionAndPermissionUtils::isHeadlessSystemUserMode() {
178 // Checks if the device is running in headless system user mode
179 // by checking the property ro.fw.mu.headless_system_user.
180 char value[PROPERTY_VALUE_MAX] = {0};
181 property_get("ro.fw.mu.headless_system_user", value, "");
182 return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
183}
184
185bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
186 // Returns false if this is not an automotive device type.
Austin Borger95a00152024-09-23 17:20:24 -0700187 if (!isAutomotiveDevice()) return false;
Austin Borger249e6592024-03-10 22:28:11 -0700188
189 // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
190 // privileged client uid used for safety critical use cases such as
191 // rear view and surround view.
192 return uid == AID_AUTOMOTIVE_EVS;
193}
194
Austin Borgerce55edb2024-09-23 15:12:56 -0700195std::string AttributionAndPermissionUtils::getPackageNameFromUid(int clientUid) const {
196 std::string packageName("");
197
198 sp<IPermissionController> permCtrl = getPermissionController();
199 if (permCtrl == nullptr) {
200 // Return empty package name and the further interaction
201 // with camera will likely fail
202 return packageName;
203 }
204
205 Vector<String16> packages;
206
207 permCtrl->getPackagesForUid(clientUid, packages);
208
209 if (packages.isEmpty()) {
210 ALOGE("No packages for calling UID %d", clientUid);
211 // Return empty package name and the further interaction
212 // with camera will likely fail
213 return packageName;
214 }
215
216 // Arbitrarily pick the first name in the list
217 packageName = toStdString(packages[0]);
218
219 return packageName;
220}
221
Austin Borger95a00152024-09-23 17:20:24 -0700222status_t AttributionAndPermissionUtils::getUidForPackage(const std::string& packageName, int userId,
223 /*inout*/ uid_t& uid, int err) {
Austin Borger249e6592024-03-10 22:28:11 -0700224 PermissionController pc;
225 uid = pc.getPackageUid(toString16(packageName), 0);
226 if (uid <= 0) {
227 ALOGE("Unknown package: '%s'", packageName.c_str());
228 dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
229 return BAD_VALUE;
230 }
231
232 if (userId < 0) {
233 ALOGE("Invalid user: %d", userId);
234 dprintf(err, "Invalid user: %d\n", userId);
235 return BAD_VALUE;
236 }
237
238 uid = multiuser_get_uid(userId, uid);
239 return NO_ERROR;
240}
241
242bool AttributionAndPermissionUtils::isCallerCameraServerNotDelegating() {
Austin Borger22c5c852024-03-08 13:31:36 -0800243 return (getCallingPid() == getpid());
Austin Borger249e6592024-03-10 22:28:11 -0700244}
245
Austin Borger95a00152024-09-23 17:20:24 -0700246bool AttributionAndPermissionUtils::hasPermissionsForCamera(
247 const std::string& cameraId, const AttributionSourceState& attributionSource) {
248 return checkPermissionForPreflight(cameraId, sCameraPermission, attributionSource,
249 std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700250}
251
Austin Borger95a00152024-09-23 17:20:24 -0700252bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(
253 const std::string& cameraId, const AttributionSourceState& attributionSource,
254 bool checkCameraPermissions) {
255 bool systemCameraPermission =
256 checkPermissionForPreflight(cameraId, sSystemCameraPermission, attributionSource,
257 std::string(), AppOpsManager::OP_NONE);
258 return systemCameraPermission &&
259 (!checkCameraPermissions || hasPermissionsForCamera(cameraId, attributionSource));
Austin Borger249e6592024-03-10 22:28:11 -0700260}
261
262bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
263 const std::string& cameraId, const AttributionSourceState& attributionSource) {
264 return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700265 attributionSource, std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700266}
267
268bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
269 const AttributionSourceState& attributionSource) {
270 return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700271 attributionSource, std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700272}
273
274bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
275 const AttributionSourceState& attributionSource) {
276 return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700277 attributionSource, std::string(), AppOpsManager::OP_NONE);
278}
279
280bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(
281 const std::string& cameraId, const AttributionSourceState& attributionSource) {
282 if (isAutomotivePrivilegedClient(attributionSource.uid)) {
283 // If cameraId is empty, then it means that this check is not used for the
284 // purpose of accessing a specific camera, hence grant permission just
285 // based on uid to the automotive privileged client.
286 if (cameraId.empty()) return true;
287
288 auto cameraService = mCameraService.promote();
289 if (cameraService == nullptr) {
290 ALOGE("%s: CameraService unavailable.", __FUNCTION__);
291 return false;
292 }
293
294 // If this call is used for accessing a specific camera then cam_id must be provided.
295 // In that case, only pre-grants the permission for accessing the exterior system only
296 // camera.
297 return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
298 }
299
300 return false;
301}
302
303void AttributionAndPermissionUtils::resolveAttributionPackage(
304 AttributionSourceState& resolvedAttributionSource) {
305 if (resolvedAttributionSource.packageName.has_value() &&
306 resolvedAttributionSource.packageName->size() > 0) {
307 return;
308 }
309
310 // NDK calls don't come with package names, but we need one for various cases.
311 // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
312 // do exist. For all authentication cases, all packages under the same UID get the
313 // same permissions, so picking any associated package name is sufficient. For some
314 // other cases, this may give inaccurate names for clients in logs.
315 resolvedAttributionSource.packageName = getPackageNameFromUid(resolvedAttributionSource.uid);
316}
317
318// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
319bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
320 int callingUid = getCallingUid();
321
322 bool validUid = true;
323 if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
324 clientUid = callingUid;
325 } else {
326 validUid = isTrustedCallingUid(callingUid);
327 if (flags::use_context_attribution_source()) {
328 validUid = validUid || (clientUid == callingUid);
329 }
330 }
331
332 return validUid;
333}
334
335// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
336bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
337 int callingUid = getCallingUid();
338 int callingPid = getCallingPid();
339
340 bool validPid = true;
341 if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
342 clientPid = callingPid;
343 } else {
344 validPid = isTrustedCallingUid(callingUid);
345 if (flags::use_context_attribution_source()) {
346 validPid = validPid || (clientPid == callingPid);
347 }
348 }
349
350 return validPid;
351}
352
353binder::Status AttributionAndPermissionUtils::errorNotTrusted(
354 int clientPid, int clientUid, const std::string& methodName,
355 const std::optional<std::string>& cameraIdMaybe, const std::string& clientName,
356 bool isPid) const {
357 int callingPid = getCallingPid();
358 int callingUid = getCallingUid();
359 ALOGE("CameraService::%s X (calling PID %d, calling UID %d) rejected "
360 "(don't trust %s %d)",
361 methodName.c_str(), callingPid, callingUid, isPid ? "clientPid" : "clientUid",
362 isPid ? clientPid : clientUid);
363 return STATUS_ERROR_FMT(hardware::ICameraService::ERROR_PERMISSION_DENIED,
364 "Untrusted caller (calling PID %d, UID %d) trying to "
365 "forward camera access to camera %s for client %s (PID %d, UID %d)",
366 getCallingPid(), getCallingUid(), cameraIdMaybe.value_or("N/A").c_str(),
367 clientName.c_str(), clientPid, clientUid);
Austin Borger249e6592024-03-10 22:28:11 -0700368}
369
Austin Borgerce55edb2024-09-23 15:12:56 -0700370const sp<IPermissionController>& AttributionAndPermissionUtils::getPermissionController() const {
371 static const char* kPermissionControllerService = "permission";
372 static thread_local sp<IPermissionController> sPermissionController = nullptr;
373
374 if (sPermissionController == nullptr ||
Austin Borger95a00152024-09-23 17:20:24 -0700375 !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
Austin Borgerce55edb2024-09-23 15:12:56 -0700376 sp<IServiceManager> sm = defaultServiceManager();
377 sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
378 if (binder == nullptr) {
379 ALOGE("%s: Could not get permission service", __FUNCTION__);
380 sPermissionController = nullptr;
381 } else {
382 sPermissionController = interface_cast<IPermissionController>(binder);
383 }
384 }
385
386 return sPermissionController;
387}
388
Austin Borger249e6592024-03-10 22:28:11 -0700389} // namespace android