Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9d93277 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

fix a memory corruption where a SF Client could be used after it's been destroyed

parent cd8c5e29
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ const char* const Layer::typeID = "Layer";

// ---------------------------------------------------------------------------

Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i)
Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& c, int32_t i)
    :   LayerBaseClient(flinger, display, c, i),
        mSecure(false),
        mFrontBufferIndex(1),
@@ -100,8 +100,7 @@ status_t Layer::ditch()
    return NO_ERROR;
}

status_t Layer::setBuffers( Client* client,
                            uint32_t w, uint32_t h,
status_t Layer::setBuffers( uint32_t w, uint32_t h,
                            PixelFormat format, uint32_t flags)
{
    PixelFormatInfo info;
@@ -285,6 +284,14 @@ sp<SurfaceBuffer> Layer::peekBuffer()
    return buffer;
}

void Layer::scheduleBroadcast()
{
    sp<Client> ourClient(client.promote());
    if (ourClient != 0) {
        mFlinger->scheduleBroadcast(ourClient);
    }
}

uint32_t Layer::doTransaction(uint32_t flags)
{
    const Layer::State& front(drawingState());
@@ -380,7 +387,7 @@ uint32_t Layer::doTransaction(uint32_t flags)
                        eResizeBuffer1 : eResizeBuffer0;
                android_atomic_and(~mask, &(lcblk->swapState));
                // since a buffer became available, we can let the client go...
                mFlinger->scheduleBroadcast(client);
                scheduleBroadcast();
                mResizeTransactionDone = true;

                // we're being resized and there is a freeze display request,
@@ -489,7 +496,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
    if (UNLIKELY(state & eInvalidSurface)) {
        // if eInvalidSurface is set, this means the surface
        // became invalid during a transaction (NO_MEMORY for instance)
        mFlinger->scheduleBroadcast(client);
        scheduleBroadcast();
        return;
    }

@@ -627,7 +634,7 @@ void Layer::unlockPageFlip(

        // client could be blocked, so signal them so they get a
        // chance to reevaluate their condition.
        mFlinger->scheduleBroadcast(client);
        scheduleBroadcast();
    }
}

@@ -638,7 +645,7 @@ void Layer::finishPageFlip()
                "layer %p wasn't locked!", this);
        android_atomic_and(~eBusy, &(lcblk->swapState));
    }
    mFlinger->scheduleBroadcast(client);
    scheduleBroadcast();
}

// ---------------------------------------------------------------------------
+3 −3
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ public:
    virtual uint32_t getTypeInfo() const { return typeInfo; }

                 Layer(SurfaceFlinger* flinger, DisplayID display,
                         Client* c, int32_t i);
                         const sp<Client>& client, int32_t i);

        virtual ~Layer();

@@ -66,8 +66,7 @@ public:
        return frontBuffer().getPixelFormat();
    }

    status_t setBuffers(    Client* client,
                            uint32_t w, uint32_t h,
    status_t setBuffers(    uint32_t w, uint32_t h,
                            PixelFormat format, uint32_t flags=0);

    virtual void onDraw(const Region& clip) const;
@@ -105,6 +104,7 @@ private:
    Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
    sp<SurfaceBuffer> peekBuffer();
    void destroy();
    void scheduleBroadcast();

    
    class SurfaceLayer : public LayerBaseClient::Surface
+11 −7
Original line number Diff line number Diff line
@@ -640,16 +640,17 @@ regular:
// ---------------------------------------------------------------------------

LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
        Client* c, int32_t i)
    : LayerBase(flinger, display), client(c),
      lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
        const sp<Client>& client, int32_t i)
    : LayerBase(flinger, display), client(client),
      lcblk( client!=0 ? &(client->ctrlblk->layers[i]) : 0 ),
      mIndex(i)
{
}

void LayerBaseClient::onFirstRef()
{    
    if (client) {
    sp<Client> client(this->client.promote());
    if (client != 0) {
        client->bindLayer(this, mIndex);
        // Initialize this layer's control block
        memset(this->lcblk, 0, sizeof(layer_cblk_t));
@@ -661,13 +662,16 @@ void LayerBaseClient::onFirstRef()

LayerBaseClient::~LayerBaseClient()
{
    if (client) {
    sp<Client> client(this->client.promote());
    if (client != 0) {
        client->free(mIndex);
    }
}

int32_t LayerBaseClient::serverIndex() const {
    if (client) {
int32_t LayerBaseClient::serverIndex() const 
{
    sp<Client> client(this->client.promote());
    if (client != 0) {
        return (client->cid<<16)|mIndex;
    }
    return 0xFFFF0000 | mIndex;
+2 −2
Original line number Diff line number Diff line
@@ -297,11 +297,11 @@ public:
    virtual uint32_t getTypeInfo() const { return typeInfo; }

    LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
            Client* client, int32_t i);
            const sp<Client>& client, int32_t i);
    virtual ~LayerBaseClient();
    virtual void onFirstRef();

    Client*             const client;
    wp<Client>          client;
    layer_cblk_t*       const lcblk;

    inline  uint32_t    getIdentity() const { return mIdentity; }
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ const char* const LayerBlur::typeID = "LayerBlur";
// ---------------------------------------------------------------------------

LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
        Client* client, int32_t i)
        const sp<Client>& client, int32_t i)
     : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
     mRefreshCache(true), mCacheAge(0), mTextureName(-1U)
{
Loading