Prevent camera access when sensor privacy is enabled

Test: Manually verified apps cannot use the camera when sensor privacy \
      is enabled.
Bug: 110842805

Change-Id: Ic3fed8272e90f3f64e0f6c342569c27e1a476014
gugelfrei
Michael Groover 6 years ago
parent abf2929e8d
commit d1d435a76b

@ -83,6 +83,7 @@ cc_library_shared {
"libhidltransport",
"libjpeg",
"libmemunreachable",
"libsensorprivacy",
"libstagefright_foundation",
"android.frameworks.cameraservice.common@2.0",
"android.frameworks.cameraservice.service@2.0",
@ -100,6 +101,7 @@ cc_library_shared {
"libbinder",
"libcamera_client",
"libfmq",
"libsensorprivacy",
],
include_dirs: [

@ -54,6 +54,7 @@
#include <media/IMediaHTTPService.h>
#include <media/mediaplayer.h>
#include <mediautils/BatteryNotifier.h>
#include <sensorprivacy/SensorPrivacyManager.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/String16.h>
@ -145,6 +146,8 @@ void CameraService::onFirstRef()
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
mSensorPrivacyPolicy->registerSelf();
sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);
if (hcs->registerAsService() != android::OK) {
ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0",
@ -230,6 +233,7 @@ void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeS
CameraService::~CameraService() {
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
mUidPolicy->unregisterSelf();
mSensorPrivacyPolicy->unregisterSelf();
}
void CameraService::onNewProviderRegistered() {
@ -951,6 +955,14 @@ Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
clientName8.string(), clientUid, clientPid, cameraId.string());
}
// If sensor privacy is enabled then prevent access to the camera
if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
ALOGE("Access Denial: cannot use the camera when sensor privacy is enabled");
return STATUS_ERROR_FMT(ERROR_DISABLED,
"Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" when sensor privacy "
"is enabled", clientName8.string(), clientUid, clientPid, cameraId.string());
}
// Only use passed in clientPid to check permission. Use calling PID as the client PID that's
// connected to camera service directly.
originalClientPid = clientPid;
@ -1603,9 +1615,10 @@ Status CameraService::notifySystemEvent(int32_t eventId,
switch(eventId) {
case ICameraService::EVENT_USER_SWITCHED: {
// Try to register for UID policy updates, in case we're recovering
// Try to register for UID and sensor privacy policy updates, in case we're recovering
// from a system server crash
mUidPolicy->registerSelf();
mSensorPrivacyPolicy->registerSelf();
doUserSwitch(/*newUserIds*/ args);
break;
}
@ -2576,6 +2589,59 @@ void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPack
}
}
// ----------------------------------------------------------------------------
// SensorPrivacyPolicy
// ----------------------------------------------------------------------------
void CameraService::SensorPrivacyPolicy::registerSelf() {
Mutex::Autolock _l(mSensorPrivacyLock);
if (mRegistered) {
return;
}
SensorPrivacyManager spm;
spm.addSensorPrivacyListener(this);
mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
status_t res = spm.linkToDeath(this);
if (res == OK) {
mRegistered = true;
ALOGV("SensorPrivacyPolicy: Registered with SensorPrivacyManager");
}
}
void CameraService::SensorPrivacyPolicy::unregisterSelf() {
Mutex::Autolock _l(mSensorPrivacyLock);
SensorPrivacyManager spm;
spm.removeSensorPrivacyListener(this);
spm.unlinkToDeath(this);
mRegistered = false;
ALOGV("SensorPrivacyPolicy: Unregistered with SensorPrivacyManager");
}
bool CameraService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
Mutex::Autolock _l(mSensorPrivacyLock);
return mSensorPrivacyEnabled;
}
binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
{
Mutex::Autolock _l(mSensorPrivacyLock);
mSensorPrivacyEnabled = enabled;
}
// if sensor privacy is enabled then block all clients from accessing the camera
if (enabled) {
sp<CameraService> service = mService.promote();
if (service != nullptr) {
service->blockAllClients();
}
}
return binder::Status::ok();
}
void CameraService::SensorPrivacyPolicy::binderDied(const wp<IBinder>& /*who*/) {
Mutex::Autolock _l(mSensorPrivacyLock);
ALOGV("SensorPrivacyPolicy: SensorPrivacyManager has died");
mRegistered = false;
}
// ----------------------------------------------------------------------------
// CameraState
// ----------------------------------------------------------------------------
@ -3062,6 +3128,18 @@ void CameraService::blockClientsForUid(uid_t uid) {
}
}
void CameraService::blockAllClients() {
const auto clients = mActiveClientManager.getAll();
for (auto& current : clients) {
if (current != nullptr) {
const auto basicClient = current->getValue();
if (basicClient.get() != nullptr) {
basicClient->block();
}
}
}
}
// NOTE: This is a remote API - make sure all args are validated
status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {

@ -18,6 +18,7 @@
#define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
#include <android/hardware/BnCameraService.h>
#include <android/hardware/BnSensorPrivacyListener.h>
#include <android/hardware/ICameraServiceListener.h>
#include <android/hardware/ICameraServiceProxy.h>
@ -554,8 +555,35 @@ private:
std::unordered_map<uid_t, bool> mOverrideUids;
}; // class UidPolicy
// If sensor privacy is enabled then all apps, including those that are active, should be
// prevented from accessing the camera.
class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener,
public virtual IBinder::DeathRecipient {
public:
explicit SensorPrivacyPolicy(wp<CameraService> service)
: mService(service), mSensorPrivacyEnabled(false), mRegistered(false) {}
void registerSelf();
void unregisterSelf();
bool isSensorPrivacyEnabled();
binder::Status onSensorPrivacyChanged(bool enabled);
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
private:
wp<CameraService> mService;
Mutex mSensorPrivacyLock;
bool mSensorPrivacyEnabled;
bool mRegistered;
};
sp<UidPolicy> mUidPolicy;
sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
// Delay-load the Camera HAL module
virtual void onFirstRef();
@ -825,6 +853,9 @@ private:
// Blocks all clients from the UID
void blockClientsForUid(uid_t uid);
// Blocks all active clients.
void blockAllClients();
// Overrides the UID state as if it is idle
status_t handleSetUidState(const Vector<String16>& args, int err);

Loading…
Cancel
Save