diff options
-rw-r--r-- | android_keymaster/serializable.cpp | 23 | ||||
-rw-r--r-- | include/keymaster/serializable.h | 17 | ||||
-rw-r--r-- | tests/fuzzers/buffer_fuzz.cpp | 3 |
3 files changed, 25 insertions, 18 deletions
diff --git a/android_keymaster/serializable.cpp b/android_keymaster/serializable.cpp index b1f1e31..fe0d742 100644 --- a/android_keymaster/serializable.cpp +++ b/android_keymaster/serializable.cpp @@ -74,6 +74,10 @@ bool copy_size_and_data_from_buf(const uint8_t** buf_ptr, const uint8_t* end, si bool Buffer::reserve(size_t size) { if (available_write() < size) { + if (!valid_buffer_state()) { + return false; + } + size_t new_size = buffer_size_ + size - available_write(); uint8_t* new_buffer = new (std::nothrow) uint8_t[new_size]; if (!new_buffer) return false; @@ -121,6 +125,10 @@ size_t Buffer::available_read() const { return write_position_ - read_position_; } +bool Buffer::valid_buffer_state() const { + return (buffer_size_ >= write_position_) && (write_position_ >= read_position_); +} + bool Buffer::write(const uint8_t* src, size_t write_length) { if (available_write() < write_length) return false; memcpy(buffer_.get() + write_position_, src, write_length); @@ -135,6 +143,21 @@ bool Buffer::read(uint8_t* dest, size_t read_length) { return true; } +bool Buffer::advance_write(int distance) { + if (distance < 0) { + return false; + } + + const size_t validated_distance = static_cast<size_t>(distance); + const size_t new_write_position = write_position_ + validated_distance; + + if (new_write_position <= buffer_size_ && new_write_position >= write_position_) { + write_position_ = new_write_position; + return true; + } + return false; +} + size_t Buffer::SerializedSize() const { return sizeof(uint32_t) + available_read(); } diff --git a/include/keymaster/serializable.h b/include/keymaster/serializable.h index fdc97f1..4532485 100644 --- a/include/keymaster/serializable.h +++ b/include/keymaster/serializable.h @@ -238,26 +238,13 @@ class Buffer : public Serializable { size_t available_write() const; size_t available_read() const; size_t buffer_size() const { return buffer_size_; } + bool valid_buffer_state() const; bool write(const uint8_t* src, size_t write_length); bool read(uint8_t* dest, size_t read_length); const uint8_t* peek_read() const { return buffer_.get() + read_position_; } - bool advance_read(int distance) { - if (static_cast<size_t>(read_position_ + distance) <= write_position_) { - read_position_ += distance; - return true; - } - return false; - } uint8_t* peek_write() { return buffer_.get() + write_position_; } - bool advance_write(int distance) { - if (static_cast<size_t>(write_position_ + distance) <= buffer_size_) { - write_position_ += distance; - return true; - } - return false; - } - + bool advance_write(int distance); size_t SerializedSize() const; uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const; bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end); diff --git a/tests/fuzzers/buffer_fuzz.cpp b/tests/fuzzers/buffer_fuzz.cpp index 0b02b3f..e0928cd 100644 --- a/tests/fuzzers/buffer_fuzz.cpp +++ b/tests/fuzzers/buffer_fuzz.cpp @@ -37,9 +37,6 @@ std::vector<std::function<void(keymaster::Buffer*, FuzzedDataProvider*)>> operat buf->reserve(fdp->ConsumeIntegralInRange<int>(kMinBufferSize, kMaxBufferSize)); }, [](keymaster::Buffer* buf, FuzzedDataProvider* fdp) -> void { - buf->advance_read(fdp->ConsumeIntegral<int>()); - }, - [](keymaster::Buffer* buf, FuzzedDataProvider* fdp) -> void { buf->advance_write(fdp->ConsumeIntegral<int>()); }, [](keymaster::Buffer* buf, FuzzedDataProvider* fdp) -> void { |