From 0bbf8b213ad96051357e3ad6d6d2808bfa31a59a Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Thu, 30 Apr 2015 14:35:42 -0700 Subject: camera2: Fix fuzztesting segfault in connect. Bug: 20721655 Change-Id: I0d974cad19683a8c86a76dac7f61ac0010bd977a --- services/camera/libcameraservice/CameraService.cpp | 16 ++++++++++++++-- services/camera/libcameraservice/CameraService.h | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'services/camera/libcameraservice') diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 8c5c43a..e28464d 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -890,9 +890,12 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien if (current != nullptr) { auto clientSp = current->getValue(); if (clientSp.get() != nullptr) { // should never be needed - if (clientSp->getRemote() == remoteCallback) { + if (!clientSp->canCastToApiClient(effectiveApiLevel)) { + ALOGW("CameraService connect called from same client, but with a different" + " API level, evicting prior client..."); + } else if (clientSp->getRemote() == remoteCallback) { ALOGI("CameraService::connect X (PID %d) (second call from same" - "app binder, returning the same client)", clientPid); + " app binder, returning the same client)", clientPid); *client = clientSp; return NO_ERROR; } @@ -1754,6 +1757,11 @@ int CameraService::BasicClient::getClientPid() const { return mClientPid; } +bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const { + // Defaults to API2. + return level == API_2; +} + status_t CameraService::BasicClient::startCameraOps() { int32_t res; // Notify app ops that the camera is not available @@ -1866,6 +1874,10 @@ void CameraService::Client::disconnect() { BasicClient::disconnect(); } +bool CameraService::Client::canCastToApiClient(apiLevel level) const { + return level == API_1; +} + CameraService::Client::OpsCallback::OpsCallback(wp client): mClient(client) { } diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 84e61c5..a8b4c4a 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -65,6 +65,7 @@ public: class Client; class BasicClient; + // The effective API level. The Camera2 API running in LEGACY mode counts as API_1. enum apiLevel { API_1 = 1, API_2 = 2 @@ -215,6 +216,10 @@ public: // Get the PID of the application client using this virtual int getClientPid() const; + + // Check what API level is used for this client. This is used to determine which + // superclass this can be cast to. + virtual bool canCastToApiClient(apiLevel level) const; protected: BasicClient(const sp& cameraService, const sp& remoteCallback, @@ -323,6 +328,10 @@ public: virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode, const CaptureResultExtras& resultExtras); + + // Check what API level is used for this client. This is used to determine which + // superclass this can be cast to. + virtual bool canCastToApiClient(apiLevel level) const; protected: // Convert client from cookie. static sp getClientFromCookie(void* user); -- cgit v1.1