graphics: fix a potential use after free
We cannot lookup _and_ update buffer cache entry in lookupBuffer.
The old buffer is still in use by hwcomposer2. Add updateBuffer to
do the update after the new buffer has replaced the old buffer in
hwcomposer2.
While at it, s/BufferClone/BufferCacheEntry/g.
Bug: 36064845
Test: manual
Change-Id: I59b61c0198ad528c40020fdebbe27a6cc359226f
diff --git a/graphics/composer/2.1/default/ComposerClient.h b/graphics/composer/2.1/default/ComposerClient.h
index d351cfb..14da1f8 100644
--- a/graphics/composer/2.1/default/ComposerClient.h
+++ b/graphics/composer/2.1/default/ComposerClient.h
@@ -31,18 +31,18 @@
namespace V2_1 {
namespace implementation {
-class BufferClone {
+class BufferCacheEntry {
public:
- BufferClone();
- BufferClone(BufferClone&& other);
+ BufferCacheEntry();
+ BufferCacheEntry(BufferCacheEntry&& other);
- BufferClone(const BufferClone& other) = delete;
- BufferClone& operator=(const BufferClone& other) = delete;
+ BufferCacheEntry(const BufferCacheEntry& other) = delete;
+ BufferCacheEntry& operator=(const BufferCacheEntry& other) = delete;
- BufferClone& operator=(buffer_handle_t handle);
- ~BufferClone();
+ BufferCacheEntry& operator=(buffer_handle_t handle);
+ ~BufferCacheEntry();
- operator buffer_handle_t() const { return mHandle; }
+ buffer_handle_t getHandle() const { return mHandle; }
private:
void clear();
@@ -108,15 +108,15 @@
protected:
struct LayerBuffers {
- std::vector<BufferClone> Buffers;
- BufferClone SidebandStream;
+ std::vector<BufferCacheEntry> Buffers;
+ BufferCacheEntry SidebandStream;
};
struct DisplayData {
bool IsVirtual;
- std::vector<BufferClone> ClientTargets;
- std::vector<BufferClone> OutputBuffers;
+ std::vector<BufferCacheEntry> ClientTargets;
+ std::vector<BufferCacheEntry> OutputBuffers;
std::unordered_map<Layer, LayerBuffers> Layers;
@@ -167,12 +167,23 @@
LAYER_BUFFERS,
LAYER_SIDEBAND_STREAMS,
};
+ Error lookupBufferCacheEntryLocked(BufferCache cache, uint32_t slot,
+ BufferCacheEntry** outEntry);
Error lookupBuffer(BufferCache cache, uint32_t slot,
- bool useCache, buffer_handle_t& handle);
+ bool useCache, buffer_handle_t handle,
+ buffer_handle_t* outHandle);
+ void updateBuffer(BufferCache cache, uint32_t slot,
+ bool useCache, buffer_handle_t handle);
- Error lookupLayerSidebandStream(buffer_handle_t& handle)
+ Error lookupLayerSidebandStream(buffer_handle_t handle,
+ buffer_handle_t* outHandle)
{
return lookupBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
+ 0, false, handle, outHandle);
+ }
+ void updateLayerSidebandStream(buffer_handle_t handle)
+ {
+ updateBuffer(BufferCache::LAYER_SIDEBAND_STREAMS,
0, false, handle);
}