diff options
author | 2024-08-09 10:47:08 -0700 | |
---|---|---|
committer | 2024-08-09 10:47:08 -0700 | |
commit | 707263e428bf711a19e55a48581c3d79c5a6f62f (patch) | |
tree | 168606d772f77a183df2cad5df1ade4bbb758c9f | |
parent | ac310d16b1f8f808555f7ce3633b884bb92c0b36 (diff) |
[res] Zero big buffer memory on backing up
When a memory chunk gets returned into BigBuffer, it may have
some data written already. BigBuffer is supposed to give out
zeroed memory, so BackUp() needs to zero it as well
Bug: 336758568
Bug: 342579978
Test: unit test + bundletool on the attached aab
Flag: EXEMPT bugfix
Change-Id: I8ecd60e84dbe16570a92d82370d1633af72599c8
-rw-r--r-- | libs/androidfw/BigBuffer.cpp | 19 | ||||
-rw-r--r-- | libs/androidfw/include/androidfw/BigBuffer.h | 22 | ||||
-rw-r--r-- | libs/androidfw/tests/BigBuffer_test.cpp | 16 |
3 files changed, 37 insertions, 20 deletions
diff --git a/libs/androidfw/BigBuffer.cpp b/libs/androidfw/BigBuffer.cpp index bedfc49a1b0d..43b56c32fb79 100644 --- a/libs/androidfw/BigBuffer.cpp +++ b/libs/androidfw/BigBuffer.cpp @@ -17,8 +17,8 @@ #include <androidfw/BigBuffer.h> #include <algorithm> +#include <iterator> #include <memory> -#include <vector> #include "android-base/logging.h" @@ -78,10 +78,27 @@ void* BigBuffer::NextBlock(size_t* out_size) { std::string BigBuffer::to_string() const { std::string result; + result.reserve(size_); for (const Block& block : blocks_) { result.append(block.buffer.get(), block.buffer.get() + block.size); } return result; } +void BigBuffer::AppendBuffer(BigBuffer&& buffer) { + std::move(buffer.blocks_.begin(), buffer.blocks_.end(), std::back_inserter(blocks_)); + size_ += buffer.size_; + buffer.blocks_.clear(); + buffer.size_ = 0; +} + +void BigBuffer::BackUp(size_t count) { + Block& block = blocks_.back(); + block.size -= count; + size_ -= count; + // BigBuffer is supposed to always give zeroed memory, but backing up usually means + // something has been already written into the block. Erase it. + std::fill_n(block.buffer.get() + block.size, count, 0); +} + } // namespace android diff --git a/libs/androidfw/include/androidfw/BigBuffer.h b/libs/androidfw/include/androidfw/BigBuffer.h index b99a4edf9d88..c4cd7c576542 100644 --- a/libs/androidfw/include/androidfw/BigBuffer.h +++ b/libs/androidfw/include/androidfw/BigBuffer.h @@ -14,13 +14,12 @@ * limitations under the License. */ -#ifndef _ANDROID_BIG_BUFFER_H -#define _ANDROID_BIG_BUFFER_H +#pragma once -#include <cstring> #include <memory> #include <string> #include <type_traits> +#include <utility> #include <vector> #include "android-base/logging.h" @@ -150,24 +149,11 @@ inline size_t BigBuffer::block_size() const { template <typename T> inline T* BigBuffer::NextBlock(size_t count) { - static_assert(std::is_standard_layout<T>::value, "T must be standard_layout type"); + static_assert(std::is_standard_layout_v<T>, "T must be standard_layout type"); CHECK(count != 0); return reinterpret_cast<T*>(NextBlockImpl(sizeof(T) * count)); } -inline void BigBuffer::BackUp(size_t count) { - Block& block = blocks_.back(); - block.size -= count; - size_ -= count; -} - -inline void BigBuffer::AppendBuffer(BigBuffer&& buffer) { - std::move(buffer.blocks_.begin(), buffer.blocks_.end(), std::back_inserter(blocks_)); - size_ += buffer.size_; - buffer.blocks_.clear(); - buffer.size_ = 0; -} - inline void BigBuffer::Pad(size_t bytes) { NextBlock<char>(bytes); } @@ -188,5 +174,3 @@ inline BigBuffer::const_iterator BigBuffer::end() const { } } // namespace android - -#endif // _ANDROID_BIG_BUFFER_H diff --git a/libs/androidfw/tests/BigBuffer_test.cpp b/libs/androidfw/tests/BigBuffer_test.cpp index 382d21e20846..7e38f1758057 100644 --- a/libs/androidfw/tests/BigBuffer_test.cpp +++ b/libs/androidfw/tests/BigBuffer_test.cpp @@ -98,4 +98,20 @@ TEST(BigBufferTest, PadAndAlignProperly) { ASSERT_EQ(8u, buffer.size()); } +TEST(BigBufferTest, BackUpZeroed) { + BigBuffer buffer(16); + + auto block = buffer.NextBlock<char>(2); + ASSERT_TRUE(block != nullptr); + ASSERT_EQ(2u, buffer.size()); + block[0] = 0x01; + block[1] = 0x02; + buffer.BackUp(1); + ASSERT_EQ(1u, buffer.size()); + auto new_block = buffer.NextBlock<char>(1); + ASSERT_TRUE(new_block != nullptr); + ASSERT_EQ(2u, buffer.size()); + ASSERT_EQ(0, *new_block); +} + } // namespace android |