From 7b2c3cd09940674d1b96a7f68e73bd81068a921c Mon Sep 17 00:00:00 2001 From: dog Date: Fri, 15 Oct 2021 20:42:08 +0800 Subject: [PATCH] fix writeString read overflow addressSanitizer Signed-off-by: hongtao --- base/include/parcel.h | 2 ++ base/src/parcel.cpp | 51 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/base/include/parcel.h b/base/include/parcel.h index 331c947..5ea29b2 100755 --- a/base/include/parcel.h +++ b/base/include/parcel.h @@ -138,6 +138,8 @@ public: bool WriteBuffer(const void *data, size_t size); + bool WriteBufferAddTerminator(const void *data, size_t size, size_t typeSize); + bool WriteUnpadBuffer(const void *data, size_t size); bool WriteCString(const char *value); diff --git a/base/src/parcel.cpp b/base/src/parcel.cpp index 32c3546..35b4832 100755 --- a/base/src/parcel.cpp +++ b/base/src/parcel.cpp @@ -349,6 +349,37 @@ bool Parcel::WriteBuffer(const void *data, size_t size) return false; } +bool Parcel::WriteBufferAddTerminator(const void *data, size_t size, size_t typeSize) +{ + if (data == nullptr || size < typeSize) { + return false; + } + + size_t padSize = GetPadSize(size); + size_t desireCapacity = size + padSize; + + // in case of desireCapacity overflow + if (desireCapacity < size || desireCapacity < padSize) { + return false; + } + + if (EnsureWritableCapacity(desireCapacity)) { + if (!WriteDataBytes(data, size - typeSize)) { + return false; + } + + // Reserved for 32 bits + const char terminator[] = {0, 0, 0, 0}; + if (!WriteDataBytes(terminator, typeSize)) { + return false; + } + WritePadBytes(padSize); + return true; + } + + return false; +} + bool Parcel::WriteUnpadBuffer(const void *data, size_t size) { return WriteBuffer(data, size); @@ -471,13 +502,14 @@ bool Parcel::WriteString(const std::string &value) } int32_t dataLength = value.length(); - int32_t desireCapacity = dataLength + sizeof(char); + int32_t typeSize = sizeof(char); + int32_t desireCapacity = dataLength + typeSize; if (!Write(dataLength)) { return false; } - return WriteBuffer(value.data(), desireCapacity); + return WriteBufferAddTerminator(value.data(), desireCapacity, typeSize); } bool Parcel::WriteString16(const std::u16string &value) @@ -487,13 +519,14 @@ bool Parcel::WriteString16(const std::u16string &value) } int32_t dataLength = value.length(); - int32_t desireCapacity = (dataLength + 1) * sizeof(char16_t); + int32_t typeSize = sizeof(char16_t); + int32_t desireCapacity = (dataLength + 1) * typeSize; if (!Write(dataLength)) { return false; } - return WriteBuffer(value.data(), desireCapacity); + return WriteBufferAddTerminator(value.data(), desireCapacity, typeSize); } bool Parcel::WriteString16WithLength(const char16_t *value, size_t len) @@ -503,14 +536,15 @@ bool Parcel::WriteString16WithLength(const char16_t *value, size_t len) } int32_t dataLength = len; - int32_t desireCapacity = (dataLength + 1) * sizeof(char16_t); + int32_t typeSize = sizeof(char16_t); + int32_t desireCapacity = (dataLength + 1) * typeSize; std::u16string u16str(reinterpret_cast(value), len); if (!Write(dataLength)) { return false; } - return WriteBuffer(u16str.data(), desireCapacity); + return WriteBufferAddTerminator(u16str.data(), desireCapacity, typeSize); } bool Parcel::WriteString8WithLength(const char *value, size_t len) @@ -520,13 +554,14 @@ bool Parcel::WriteString8WithLength(const char *value, size_t len) } int32_t dataLength = len; - int32_t desireCapacity = (dataLength + 1) * sizeof(char); + int32_t typeSize = sizeof(char); + int32_t desireCapacity = (dataLength + 1) * typeSize; if (!Write(dataLength)) { return false; } - return WriteBuffer(value, desireCapacity); + return WriteBufferAddTerminator(value, desireCapacity, typeSize); } bool Parcel::EnsureObjectsCapacity() -- Gitee