blob: 37903e12831d63868cd08fde0ecdd08b82decb6f [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 Borger95a00152024-09-23 17:20:24 -070035static const std::string kPermissionServiceName = "permission";
36} // namespace
Austin Borgerce55edb2024-09-23 15:12:56 -070037
Austin Borger249e6592024-03-10 22:28:11 -070038namespace android {
39
Avichal Rakesh5788fec2024-03-15 14:39:20 -070040namespace flags = com::android::internal::camera::flags;
41
Austin Borger249e6592024-03-10 22:28:11 -070042const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
43const std::string AttributionAndPermissionUtils::sManageCameraPermission(
44 "android.permission.MANAGE_CAMERA");
Austin Borger95a00152024-09-23 17:20:24 -070045const std::string AttributionAndPermissionUtils::sCameraPermission("android.permission.CAMERA");
Austin Borger249e6592024-03-10 22:28:11 -070046const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
47 "android.permission.SYSTEM_CAMERA");
48const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
49 "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
50const std::string AttributionAndPermissionUtils::sCameraPrivacyAllowlistPermission(
51 "android.permission.CAMERA_PRIVACY_ALLOWLIST");
52const std::string AttributionAndPermissionUtils::sCameraSendSystemEventsPermission(
53 "android.permission.CAMERA_SEND_SYSTEM_EVENTS");
54const std::string AttributionAndPermissionUtils::sCameraOpenCloseListenerPermission(
55 "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
56const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
57 "android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
58
Austin Borger95a00152024-09-23 17:20:24 -070059int AttributionAndPermissionUtils::getCallingUid() const {
Austin Borger22c5c852024-03-08 13:31:36 -080060 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
61 return hardware::IPCThreadState::self()->getCallingUid();
62 }
63 return IPCThreadState::self()->getCallingUid();
64}
65
Austin Borger95a00152024-09-23 17:20:24 -070066int AttributionAndPermissionUtils::getCallingPid() const {
Austin Borger22c5c852024-03-08 13:31:36 -080067 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
68 return hardware::IPCThreadState::self()->getCallingPid();
69 }
70 return IPCThreadState::self()->getCallingPid();
71}
72
73int64_t AttributionAndPermissionUtils::clearCallingIdentity() {
74 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
75 return hardware::IPCThreadState::self()->clearCallingIdentity();
76 }
77 return IPCThreadState::self()->clearCallingIdentity();
78}
79
80void AttributionAndPermissionUtils::restoreCallingIdentity(int64_t token) {
81 if (getCurrentServingCall() == BinderCallType::HWBINDER) {
82 hardware::IPCThreadState::self()->restoreCallingIdentity(token);
83 } else {
84 IPCThreadState::self()->restoreCallingIdentity(token);
85 }
86 return;
87}
88
Austin Borger95a00152024-09-23 17:20:24 -070089binder::Status AttributionAndPermissionUtils::resolveAttributionSource(
90 /*inout*/ AttributionSourceState& resolvedAttributionSource, const std::string& methodName,
91 const std::optional<std::string>& cameraIdMaybe) {
92 // Check if we can trust clientUid
93 if (!resolveClientUid(resolvedAttributionSource.uid)) {
94 return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
95 methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
96 /* isPid= */ false);
Austin Borgerb01a8702024-07-22 16:20:34 -070097 }
98
Austin Borger95a00152024-09-23 17:20:24 -070099 resolveAttributionPackage(resolvedAttributionSource);
Austin Borgerb01a8702024-07-22 16:20:34 -0700100
Austin Borger95a00152024-09-23 17:20:24 -0700101 if (!resolveClientPid(resolvedAttributionSource.pid)) {
102 return errorNotTrusted(resolvedAttributionSource.pid, resolvedAttributionSource.uid,
103 methodName, cameraIdMaybe, *resolvedAttributionSource.packageName,
104 /* isPid= */ true);
Austin Borgerb01a8702024-07-22 16:20:34 -0700105 }
106
Austin Borger95a00152024-09-23 17:20:24 -0700107 return binder::Status::ok();
Austin Borgerb01a8702024-07-22 16:20:34 -0700108}
109
Austin Borger95a00152024-09-23 17:20:24 -0700110bool AttributionAndPermissionUtils::checkPermissionForPreflight(
111 const std::string& cameraId, const std::string& permission,
112 const AttributionSourceState& attributionSource, const std::string& message,
113 int32_t attributedOpCode) {
Austin Borger249e6592024-03-10 22:28:11 -0700114 if (checkAutomotivePrivilegedClient(cameraId, attributionSource)) {
115 return true;
116 }
117
Austin Borgerce55edb2024-09-23 15:12:56 -0700118 return mPermissionChecker->checkPermissionForPreflight(
Austin Borger95a00152024-09-23 17:20:24 -0700119 toString16(permission), attributionSource, toString16(message),
120 attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
Austin Borger249e6592024-03-10 22:28:11 -0700121}
122
123// Can camera service trust the caller based on the calling UID?
124bool AttributionAndPermissionUtils::isTrustedCallingUid(uid_t uid) {
125 switch (uid) {
126 case AID_MEDIA: // mediaserver
127 case AID_CAMERASERVER: // cameraserver
128 case AID_RADIO: // telephony
129 return true;
130 default:
131 return false;
132 }
133}
134
135bool AttributionAndPermissionUtils::isAutomotiveDevice() {
136 // Checks the property ro.hardware.type and returns true if it is
137 // automotive.
138 char value[PROPERTY_VALUE_MAX] = {0};
139 property_get("ro.hardware.type", value, "");
140 return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
141}
142
143bool AttributionAndPermissionUtils::isHeadlessSystemUserMode() {
144 // Checks if the device is running in headless system user mode
145 // by checking the property ro.fw.mu.headless_system_user.
146 char value[PROPERTY_VALUE_MAX] = {0};
147 property_get("ro.fw.mu.headless_system_user", value, "");
148 return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
149}
150
151bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
152 // Returns false if this is not an automotive device type.
Austin Borger95a00152024-09-23 17:20:24 -0700153 if (!isAutomotiveDevice()) return false;
Austin Borger249e6592024-03-10 22:28:11 -0700154
155 // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
156 // privileged client uid used for safety critical use cases such as
157 // rear view and surround view.
158 return uid == AID_AUTOMOTIVE_EVS;
159}
160
Austin Borgerce55edb2024-09-23 15:12:56 -0700161std::string AttributionAndPermissionUtils::getPackageNameFromUid(int clientUid) const {
162 std::string packageName("");
163
164 sp<IPermissionController> permCtrl = getPermissionController();
165 if (permCtrl == nullptr) {
166 // Return empty package name and the further interaction
167 // with camera will likely fail
168 return packageName;
169 }
170
171 Vector<String16> packages;
172
173 permCtrl->getPackagesForUid(clientUid, packages);
174
175 if (packages.isEmpty()) {
176 ALOGE("No packages for calling UID %d", clientUid);
177 // Return empty package name and the further interaction
178 // with camera will likely fail
179 return packageName;
180 }
181
182 // Arbitrarily pick the first name in the list
183 packageName = toStdString(packages[0]);
184
185 return packageName;
186}
187
Austin Borger95a00152024-09-23 17:20:24 -0700188status_t AttributionAndPermissionUtils::getUidForPackage(const std::string& packageName, int userId,
189 /*inout*/ uid_t& uid, int err) {
Austin Borger249e6592024-03-10 22:28:11 -0700190 PermissionController pc;
191 uid = pc.getPackageUid(toString16(packageName), 0);
192 if (uid <= 0) {
193 ALOGE("Unknown package: '%s'", packageName.c_str());
194 dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
195 return BAD_VALUE;
196 }
197
198 if (userId < 0) {
199 ALOGE("Invalid user: %d", userId);
200 dprintf(err, "Invalid user: %d\n", userId);
201 return BAD_VALUE;
202 }
203
204 uid = multiuser_get_uid(userId, uid);
205 return NO_ERROR;
206}
207
208bool AttributionAndPermissionUtils::isCallerCameraServerNotDelegating() {
Austin Borger22c5c852024-03-08 13:31:36 -0800209 return (getCallingPid() == getpid());
Austin Borger249e6592024-03-10 22:28:11 -0700210}
211
Austin Borger95a00152024-09-23 17:20:24 -0700212bool AttributionAndPermissionUtils::hasPermissionsForCamera(
213 const std::string& cameraId, const AttributionSourceState& attributionSource) {
214 return checkPermissionForPreflight(cameraId, sCameraPermission, attributionSource,
215 std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700216}
217
Austin Borger95a00152024-09-23 17:20:24 -0700218bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(
219 const std::string& cameraId, const AttributionSourceState& attributionSource,
220 bool checkCameraPermissions) {
221 bool systemCameraPermission =
222 checkPermissionForPreflight(cameraId, sSystemCameraPermission, attributionSource,
223 std::string(), AppOpsManager::OP_NONE);
224 return systemCameraPermission &&
225 (!checkCameraPermissions || hasPermissionsForCamera(cameraId, attributionSource));
Austin Borger249e6592024-03-10 22:28:11 -0700226}
227
228bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
229 const std::string& cameraId, const AttributionSourceState& attributionSource) {
230 return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700231 attributionSource, std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700232}
233
234bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
235 const AttributionSourceState& attributionSource) {
236 return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700237 attributionSource, std::string(), AppOpsManager::OP_NONE);
Austin Borger249e6592024-03-10 22:28:11 -0700238}
239
240bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
241 const AttributionSourceState& attributionSource) {
242 return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
Austin Borger95a00152024-09-23 17:20:24 -0700243 attributionSource, std::string(), AppOpsManager::OP_NONE);
244}
245
246bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(
247 const std::string& cameraId, const AttributionSourceState& attributionSource) {
248 if (isAutomotivePrivilegedClient(attributionSource.uid)) {
249 // If cameraId is empty, then it means that this check is not used for the
250 // purpose of accessing a specific camera, hence grant permission just
251 // based on uid to the automotive privileged client.
252 if (cameraId.empty()) return true;
253
254 auto cameraService = mCameraService.promote();
255 if (cameraService == nullptr) {
256 ALOGE("%s: CameraService unavailable.", __FUNCTION__);
257 return false;
258 }
259
260 // If this call is used for accessing a specific camera then cam_id must be provided.
261 // In that case, only pre-grants the permission for accessing the exterior system only
262 // camera.
263 return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
264 }
265
266 return false;
267}
268
269void AttributionAndPermissionUtils::resolveAttributionPackage(
270 AttributionSourceState& resolvedAttributionSource) {
271 if (resolvedAttributionSource.packageName.has_value() &&
272 resolvedAttributionSource.packageName->size() > 0) {
273 return;
274 }
275
276 // NDK calls don't come with package names, but we need one for various cases.
277 // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
278 // do exist. For all authentication cases, all packages under the same UID get the
279 // same permissions, so picking any associated package name is sufficient. For some
280 // other cases, this may give inaccurate names for clients in logs.
281 resolvedAttributionSource.packageName = getPackageNameFromUid(resolvedAttributionSource.uid);
282}
283
284// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
285bool AttributionAndPermissionUtils::resolveClientUid(/*inout*/ int& clientUid) {
286 int callingUid = getCallingUid();
287
288 bool validUid = true;
289 if (clientUid == hardware::ICameraService::USE_CALLING_UID) {
290 clientUid = callingUid;
291 } else {
292 validUid = isTrustedCallingUid(callingUid);
293 if (flags::use_context_attribution_source()) {
294 validUid = validUid || (clientUid == callingUid);
295 }
296 }
297
298 return validUid;
299}
300
301// TODO(362551824): Make USE_CALLING_UID more explicit with a scoped enum.
302bool AttributionAndPermissionUtils::resolveClientPid(/*inout*/ int& clientPid) {
303 int callingUid = getCallingUid();
304 int callingPid = getCallingPid();
305
306 bool validPid = true;
307 if (clientPid == hardware::ICameraService::USE_CALLING_PID) {
308 clientPid = callingPid;
309 } else {
310 validPid = isTrustedCallingUid(callingUid);
311 if (flags::use_context_attribution_source()) {
312 validPid = validPid || (clientPid == callingPid);
313 }
314 }
315
316 return validPid;
317}
318
319binder::Status AttributionAndPermissionUtils::errorNotTrusted(
320 int clientPid, int clientUid, const std::string& methodName,
321 const std::optional<std::string>& cameraIdMaybe, const std::string& clientName,
322 bool isPid) const {
323 int callingPid = getCallingPid();
324 int callingUid = getCallingUid();
325 ALOGE("CameraService::%s X (calling PID %d, calling UID %d) rejected "
326 "(don't trust %s %d)",
327 methodName.c_str(), callingPid, callingUid, isPid ? "clientPid" : "clientUid",
328 isPid ? clientPid : clientUid);
329 return STATUS_ERROR_FMT(hardware::ICameraService::ERROR_PERMISSION_DENIED,
330 "Untrusted caller (calling PID %d, UID %d) trying to "
331 "forward camera access to camera %s for client %s (PID %d, UID %d)",
332 getCallingPid(), getCallingUid(), cameraIdMaybe.value_or("N/A").c_str(),
333 clientName.c_str(), clientPid, clientUid);
Austin Borger249e6592024-03-10 22:28:11 -0700334}
335
Austin Borgerce55edb2024-09-23 15:12:56 -0700336const sp<IPermissionController>& AttributionAndPermissionUtils::getPermissionController() const {
337 static const char* kPermissionControllerService = "permission";
338 static thread_local sp<IPermissionController> sPermissionController = nullptr;
339
340 if (sPermissionController == nullptr ||
Austin Borger95a00152024-09-23 17:20:24 -0700341 !IInterface::asBinder(sPermissionController)->isBinderAlive()) {
Austin Borgerce55edb2024-09-23 15:12:56 -0700342 sp<IServiceManager> sm = defaultServiceManager();
343 sp<IBinder> binder = sm->checkService(toString16(kPermissionControllerService));
344 if (binder == nullptr) {
345 ALOGE("%s: Could not get permission service", __FUNCTION__);
346 sPermissionController = nullptr;
347 } else {
348 sPermissionController = interface_cast<IPermissionController>(binder);
349 }
350 }
351
352 return sPermissionController;
353}
354
Austin Borger249e6592024-03-10 22:28:11 -0700355} // namespace android