diff options
| author | 2017-06-15 14:01:18 -0700 | |
|---|---|---|
| committer | 2017-06-16 10:54:50 -0700 | |
| commit | f456f32e0f9292d71b57b3255cde416b677faac2 (patch) | |
| tree | a61104135cac53201dc17491bdd5737c9df80e30 /services | |
| parent | c175253b6d0738aec6235ef1c2e723ad36fcd346 (diff) | |
surfaceflinger: protect Client::mParentLayer with a lock
Updates to wp<> is not atomic. Use Client::mLock to protect
mParentLayer.
Bug: 38505866
Test: camera and youtube work
Change-Id: I2739382d5bb99961a47c1011963b6f676d34eec6
Diffstat (limited to 'services')
| -rw-r--r-- | services/surfaceflinger/Client.cpp | 19 | ||||
| -rw-r--r-- | services/surfaceflinger/Client.h | 3 |
2 files changed, 17 insertions, 5 deletions
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index e9a251305f..8ba6cb9ba7 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -57,9 +57,19 @@ Client::~Client() } void Client::setParentLayer(const sp<Layer>& parentLayer) { + Mutex::Autolock _l(mLock); mParentLayer = parentLayer; } +sp<Layer> Client::getParentLayer(bool* outParentDied) const { + Mutex::Autolock _l(mLock); + sp<Layer> parent = mParentLayer.promote(); + if (outParentDied != nullptr) { + *outParentDied = (mParentLayer != nullptr && parent == nullptr); + } + return parent; +} + status_t Client::initCheck() const { return NO_ERROR; } @@ -108,7 +118,7 @@ status_t Client::onTransact( // We grant an exception in the case that the Client has a "parent layer", as its // effects will be scoped to that layer. if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0) - && (mParentLayer.promote() == nullptr)) { + && (getParentLayer() == nullptr)) { // we're called from a different process, do the real check if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) { @@ -135,11 +145,12 @@ status_t Client::createSurface( return NAME_NOT_FOUND; } } - if (parent == nullptr && mParentLayer != nullptr) { - parent = mParentLayer.promote(); + if (parent == nullptr) { + bool parentDied; + parent = getParentLayer(&parentDied); // If we had a parent, but it died, we've lost all // our capabilities. - if (parent == nullptr) { + if (parentDied) { return NAME_NOT_FOUND; } } diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index b5f98b8a6f..2aab28f37d 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -71,12 +71,13 @@ private: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); + sp<Layer> getParentLayer(bool* outParentDied = nullptr) const; + // constant sp<SurfaceFlinger> mFlinger; // protected by mLock DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers; - wp<Layer> mParentLayer; // thread-safe |