Validate client permission for HeadlessSystemUser.
If device is running in HSUM mode, if User 0 tries to access the
camera, validate that the client has the permission
android.permission.CAMERA_HEADLESS_SYSTEM_USER.
Bug:296959023
Test: Test that headless system user is not able to access
the camera without the new permission.
Change-Id: Ibc2ef43837d2e8739872697245e466d69f56f335
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index fc11518..6200489 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -6,3 +6,11 @@
description: "Flag infrastructure test flag"
bug: "292631208"
}
+
+flag {
+ namespace: "camera_platform"
+ name: "camera_hsum_permission"
+ description: "Camera access by headless system user"
+ bug: "273539631"
+}
+
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c0194b9..12a10a0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -124,6 +124,8 @@
static const std::string sManageCameraPermission("android.permission.MANAGE_CAMERA");
static const std::string sCameraPermission("android.permission.CAMERA");
static const std::string sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
+static const std::string sCameraHeadlessSystemUserPermission(
+ "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
static const std::string
sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
static const std::string sCameraOpenCloseListenerPermission(
@@ -704,6 +706,14 @@
return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
}
+static bool isHeadlessSystemUserMode() {
+ // Checks if the device is running in headless system user mode
+ // by checking the property ro.fw.mu.headless_system_user.
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.fw.mu.headless_system_user", value, "");
+ return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
+}
+
static bool isAutomotivePrivilegedClient(int32_t uid) {
// Returns false if this is not an automotive device type.
if (!isAutomotiveDevice())
@@ -793,6 +803,15 @@
return checkPermissionForSystemCamera && checkPermissionForCamera;
}
+bool CameraService::hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId,
+ int callingPid, int callingUid) const{
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ return checkPermission(cameraId, sCameraHeadlessSystemUserPermission, attributionSource,
+ std::string(), AppOpsManager::OP_NONE);
+}
+
Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
ATRACE_CALL();
Mutex::Autolock l(mServiceLock);
@@ -1643,6 +1662,18 @@
clientUserId, cameraId.c_str());
}
+ // If the System User tries to access the camera when the device is running in
+ // headless system user mode, ensure that client has the required permission
+ // CAMERA_HEADLESS_SYSTEM_USER.
+ if (isHeadlessSystemUserMode() && (clientUserId == USER_SYSTEM) &&
+ !hasPermissionsForCameraHeadlessSystemUser(cameraId, callingPid, callingUid)) {
+ ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
+ return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
+ "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" as Headless System User\
+ without camera headless system user permission",
+ clientName.c_str(), clientUid, clientPid, cameraId.c_str());
+ }
+
return Status::ok();
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 48954ca..beafe00 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -104,6 +104,9 @@
// Event log ID
static const int SN_EVENT_LOG_ID = 0x534e4554;
+ // Keep this in sync with frameworks/base/core/java/android/os/UserHandle.java
+ static const userid_t USER_SYSTEM = 0;
+
// Register camera service
static void instantiate();
@@ -656,6 +659,9 @@
bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid)
const;
+ bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId, int callingPid,
+ int callingUid) const;
+
/**
* Typesafe version of device status, containing both the HAL-layer and the service interface-
* layer values.