!17356 Drawing 代码安全整改

Merge pull request !17356 from yzj688/master
This commit is contained in:
openharmony_ci 2024-11-22 01:23:26 +00:00 committed by Gitee
commit 8edbaf0d5f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
11 changed files with 95 additions and 34 deletions

View File

@ -36,6 +36,7 @@ namespace Rosen {
namespace Drawing {
using CmdListData = std::pair<const void*, size_t>;
using NodeId = uint64_t;
constexpr size_t MAX_OPITEMSIZE = 10000;
class DRAWING_API ExtendImageObject {
public:

View File

@ -133,6 +133,8 @@ public:
void SetIsCustomTypeface(bool isCustomTypeface);
bool IsCustomTypeface() const;
void SetIsRecordCmd(bool isRecordCmd);
using DrawFunc = std::function<void(Drawing::Canvas* canvas, const Drawing::Rect* rect)>;
protected:
bool addDrawOpImmediate_ = true;
@ -150,6 +152,7 @@ private:
void GenerateCachedOpForTextblob(const TextBlob* blob, const scalar x, const scalar y, Paint& paint);
bool isCustomTextType_ = false;
bool isCustomTypeface_ = false;
bool isRecordCmd_ = false;
std::optional<Brush> customTextBrush_ = std::nullopt;
std::optional<Pen> customTextPen_ = std::nullopt;
std::stack<SaveOpState> saveOpStateStack_;

View File

@ -214,7 +214,9 @@ void DrawCmdList::CaculatePerformanceOpType()
size_t offset = offset_;
const int caculatePerformaceCount = 500; // 被测单接口用例至少出现500次以上
std::map<uint32_t, uint32_t> opTypeCountMap;
uint32_t count = 0;
do {
count++;
void* itemPtr = opAllocator_.OffsetToAddr(offset, sizeof(OpItem));
auto* curOpItemPtr = static_cast<OpItem*>(itemPtr);
if (curOpItemPtr == nullptr) {
@ -231,7 +233,7 @@ void DrawCmdList::CaculatePerformanceOpType()
opTypeCountMap[type] = 1; // 记录出现的第1次
}
offset = curOpItemPtr->GetNextOpItemOffset();
} while (offset != 0);
} while (offset != 0 && count <= MAX_OPITEMSIZE);
}
void DrawCmdList::UnmarshallingDrawOps()
@ -252,7 +254,9 @@ void DrawCmdList::UnmarshallingDrawOps()
lastOpGenSize_ = 0;
uint32_t opReplaceIndex = 0;
size_t offset = offset_;
uint32_t count = 0;
do {
count++;
void* itemPtr = opAllocator_.OffsetToAddr(offset, sizeof(OpItem));
auto* curOpItemPtr = static_cast<OpItem*>(itemPtr);
if (curOpItemPtr == nullptr) {
@ -291,7 +295,7 @@ void DrawCmdList::UnmarshallingDrawOps()
LOGD("DrawCmdList::UnmarshallingOps seek end by cache textOps");
break;
}
} while (offset != 0);
} while (offset != 0 && count <= MAX_OPITEMSIZE);
lastOpGenSize_ = opAllocator_.GetSize();
if ((int)imageAllocator_.GetSize() > 0) {
@ -452,7 +456,9 @@ void DrawCmdList::GenerateCacheByBuffer(Canvas* canvas, const Rect* rect)
size_t offset = offset_;
GenerateCachedOpItemPlayer player = { *this, canvas, rect };
uint32_t maxOffset = opAllocator_.GetSize();
uint32_t count = 0;
do {
count++;
void* itemPtr = opAllocator_.OffsetToAddr(offset, sizeof(OpItem));
auto* curOpItemPtr = static_cast<OpItem*>(itemPtr);
if (curOpItemPtr == nullptr) {
@ -471,7 +477,7 @@ void DrawCmdList::GenerateCacheByBuffer(Canvas* canvas, const Rect* rect)
}
}
offset = curOpItemPtr->GetNextOpItemOffset();
} while (offset != 0 && offset < maxOffset);
} while (offset != 0 && offset < maxOffset && count <= MAX_OPITEMSIZE);
isCached_ = true;
cachedHighContrast_ = canvas && canvas->isHighContrastEnabled();
#endif
@ -541,9 +547,11 @@ void DrawCmdList::PlaybackByBuffer(Canvas& canvas, const Rect* rect)
}
size_t offset = offset_;
if (lastOpGenSize_ != opAllocator_.GetSize()) {
uint32_t count = 0;
UnmarshallingPlayer player = { *this };
drawOpItems_.clear();
do {
count++;
void* itemPtr = opAllocator_.OffsetToAddr(offset, sizeof(OpItem));
auto* curOpItemPtr = static_cast<OpItem*>(itemPtr);
if (curOpItemPtr == nullptr) {
@ -554,7 +562,7 @@ void DrawCmdList::PlaybackByBuffer(Canvas& canvas, const Rect* rect)
drawOpItems_.emplace_back(op);
}
offset = curOpItemPtr->GetNextOpItemOffset();
} while (offset != 0);
} while (offset != 0 && count <= MAX_OPITEMSIZE);
lastOpGenSize_ = opAllocator_.GetSize();
}
for (auto op : drawOpItems_) {
@ -571,7 +579,9 @@ size_t DrawCmdList::CountTextBlobNum()
if (mode_ == DrawCmdList::UnmarshalMode::IMMEDIATE) {
size_t offset = offset_;
size_t maxOffset = opAllocator_.GetSize();
uint32_t count = 0;
do {
count++;
void* itemPtr = opAllocator_.OffsetToAddr(offset, sizeof(OpItem));
auto* curOpItemPtr = static_cast<OpItem*>(itemPtr);
if (curOpItemPtr == nullptr) {
@ -582,7 +592,7 @@ size_t DrawCmdList::CountTextBlobNum()
textBlobCnt++;
}
offset = curOpItemPtr->GetNextOpItemOffset();
} while (offset != 0 && offset < maxOffset);
} while (offset != 0 && offset < maxOffset && count <= MAX_OPITEMSIZE);
}
return textBlobCnt;
}
@ -593,7 +603,9 @@ void DrawCmdList::PatchTypefaceIds()
uint64_t replayMask = (uint64_t)1 << bitNumber;
size_t offset = offset_;
size_t maxOffset = opAllocator_.GetSize();
uint32_t count = 0;
do {
count++;
void* itemPtr = opAllocator_.OffsetToAddr(offset, sizeof(OpItem));
auto* curOpItemPtr = static_cast<OpItem*>(itemPtr);
if (curOpItemPtr == nullptr) {
@ -608,7 +620,7 @@ void DrawCmdList::PatchTypefaceIds()
}
}
offset = curOpItemPtr->GetNextOpItemOffset();
} while (offset != 0 && offset < maxOffset);
} while (offset != 0 && offset < maxOffset && count <= MAX_OPITEMSIZE);
}
void DrawCmdList::Purge()

View File

@ -39,8 +39,10 @@ std::shared_ptr<MaskCmdList> MaskCmdList::CreateFromData(const CmdListData& data
bool MaskCmdList::Playback(MaskPlayer &player) const
{
uint32_t offset = 0;
uint32_t count = 0;
size_t totalSize = opAllocator_.GetSize();
do {
count++;
if (totalSize < offset || totalSize - offset < sizeof(OpItem)) {
LOGD("MaskCmdList::Playback size error");
return false;
@ -58,7 +60,7 @@ bool MaskCmdList::Playback(MaskPlayer &player) const
LOGE("MaskCmdList::Playback failed, opItem is nullptr");
break;
}
} while (offset != 0);
} while (offset != 0 && count <= MAX_OPITEMSIZE);
return true;
}

View File

@ -110,7 +110,7 @@ bool MemAllocator::Resize(size_t size)
void* MemAllocator::Add(const void* data, size_t size)
{
if (isReadOnly_ || !data || size == 0 || size > MEM_SIZE_MAX) {
if (isReadOnly_ || !data || size == 0 || size > MEM_SIZE_MAX || size > MEM_SIZE_MAX - size_) {
return nullptr;
}
auto current = startPtr_ + size_;

View File

@ -364,6 +364,10 @@ void RecordingCanvas::DrawRecordCmd(const std::shared_ptr<RecordCmd> recordCmd,
LOGE("RecordingCanvas::DrawRecordCmd, recordCmd is nullptr!");
return;
}
if (isRecordCmd_) {
LOGE("RecordingCanvas::DrawRecordCmd, operation is unsupported!");
return;
}
if (!addDrawOpImmediate_) {
cmdList_->AddDrawOp(std::make_shared<DrawRecordCmdOpItem>(recordCmd, matrix, brush));
return;
@ -707,6 +711,11 @@ bool RecordingCanvas::IsCustomTypeface() const
return isCustomTypeface_;
}
void RecordingCanvas::SetIsRecordCmd(bool isRecordCmd)
{
isRecordCmd_ = isRecordCmd;
}
void RecordingCanvas::CheckForLazySave()
{
if (!saveOpStateStack_.empty() && saveOpStateStack_.top() == LazySaveOp) {

View File

@ -201,6 +201,10 @@ public:
return true;
}
static RSB_EXPORT bool Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val,
bool isRecordCmd = false);
static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val,
bool isRecordCmd = false);
static RSB_EXPORT bool Marshalling(Parcel& parcel, std::shared_ptr<Drawing::Typeface>& val);
static RSB_EXPORT bool Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::Typeface>& val);
static RSB_EXPORT bool Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::Image>& val);
@ -252,7 +256,6 @@ public:
DECLARE_FUNCTION_OVERLOAD(RenderParticleColorParaType)
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<ParticleRenderParams>)
DECLARE_FUNCTION_OVERLOAD(std::vector<std::shared_ptr<ParticleRenderParams>>)
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<Drawing::DrawCmdList>)
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<Drawing::RecordCmd>)
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSExtendImageObject>)
DECLARE_FUNCTION_OVERLOAD(std::shared_ptr<RSExtendImageBaseObj>)

View File

@ -33,6 +33,7 @@ Drawing::Canvas* RSRecordCmdUtils::BeginRecording(Drawing::Rect& bounds)
return nullptr;
}
extendRecordingCanvas_ = std::make_shared<ExtendRecordingCanvas>(width, height);
extendRecordingCanvas_->SetIsRecordCmd(true);
cullRect_ = bounds;
return extendRecordingCanvas_.get();
}

View File

@ -366,12 +366,13 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, RRectT<float>& val)
// Drawing::DrawCmdList
bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val)
bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val,
bool isRecordCmd)
{
return {};
}
bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val)
bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val, bool isRecordCmd)
{
return {};
}

View File

@ -75,7 +75,6 @@ namespace {
bool g_useSharedMem = true;
std::thread::id g_tid = std::thread::id();
constexpr size_t PIXELMAP_UNMARSHALLING_DEBUG_OFFSET = 12;
constexpr size_t MAX_OPITEMSIZE = 10000;
}
#define MARSHALLING_AND_UNMARSHALLING(TYPE, TYPENAME) \
@ -438,10 +437,18 @@ bool RSMarshallingHelper::ReadColorSpaceFromParcel(Parcel& parcel, std::shared_p
return false;
}
if (data->BuildWithoutCopy(dataPtr, size) == false) {
if (isMal) {
free(const_cast<void*>(dataPtr));
dataPtr = nullptr;
}
ROSEN_LOGE("data build without copy failed");
return false;
}
if (colorSpace->Deserialize(data) == false) {
if (isMal) {
free(const_cast<void*>(dataPtr));
dataPtr = nullptr;
}
ROSEN_LOGE("colorSpace deserialize failed");
return false;
}
@ -468,11 +475,23 @@ bool RSMarshallingHelper::UnmarshallingNoLazyGeneratedImage(Parcel& parcel,
int width = parcel.ReadInt32();
int height = parcel.ReadInt32();
Drawing::ColorType colorType = static_cast<Drawing::ColorType>(parcel.ReadUint32());
Drawing::AlphaType alphaType = static_cast<Drawing::AlphaType>(parcel.ReadUint32());
size_t ct = parcel.ReadUint32();
Drawing::ColorType colorType = Drawing::ColorType::COLORTYPE_UNKNOWN;
if (ct >= Drawing::ColorType::COLORTYPE_ALPHA_8 && ct <= Drawing::ColorType::COLORTYPE_RGB_888X) {
colorType = static_cast<Drawing::ColorType>(ct);
}
size_t at = parcel.ReadUint32();
Drawing::AlphaType alphaType = Drawing::AlphaType::ALPHATYPE_UNKNOWN;
if (at >= Drawing::AlphaType::ALPHATYPE_OPAQUE && at <= Drawing::AlphaType::ALPHATYPE_UNPREMUL) {
alphaType = static_cast<Drawing::AlphaType>(at);
}
auto colorSpace = std::make_shared<Drawing::ColorSpace>(Drawing::ColorSpace::ColorSpaceType::NO_TYPE);
if (!ReadColorSpaceFromParcel(parcel, colorSpace)) {
if (isMalloc) {
free(const_cast<void*>(addr));
addr = nullptr;
}
return false;
}
@ -583,8 +602,12 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<RSShader
ROSEN_LOGE("unirender: RSMarshallingHelper::Unmarshalling RSShader, data is nullptr");
return false;
}
auto shaderEffect = std::make_shared<Drawing::ShaderEffect>
(static_cast<Drawing::ShaderEffect::ShaderEffectType>(type));
Drawing::ShaderEffect::ShaderEffectType shaderEffectType = Drawing::ShaderEffect::ShaderEffectType::NO_TYPE;
if (type >= static_cast<int32_t>(Drawing::ShaderEffect::ShaderEffectType::COLOR_SHADER) &&
type <= static_cast<int32_t>(Drawing::ShaderEffect::ShaderEffectType::EXTEND_SHADER)) {
shaderEffectType = static_cast<Drawing::ShaderEffect::ShaderEffectType>(type);
}
auto shaderEffect = std::make_shared<Drawing::ShaderEffect>(shaderEffectType);
if (!shaderEffect->Deserialize(data)) {
ROSEN_LOGE("unirender: RSMarshallingHelper::Unmarshalling RSShader, Deserialize failed");
return false;
@ -1522,13 +1545,14 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, RRectT<float>& val)
// Drawing::DrawCmdList
bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val)
bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val,
bool isRecordCmd)
{
if (!val) {
return parcel.WriteInt32(-1);
}
auto opItemSize = val->GetOpItemSize();
if (opItemSize > MAX_OPITEMSIZE) {
if (opItemSize > Drawing::MAX_OPITEMSIZE) {
ROSEN_LOGE("OpItemSize is too large, OpItemSize is %{public}zu", opItemSize);
return false;
}
@ -1623,10 +1647,12 @@ bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Draw
ROSEN_LOGE("unirender: failed RSMarshallingHelper::Marshalling Drawing::DrawCmdList ExtendObject");
return ret;
}
ret &= MarshallingRecordCmdFromDrawCmdList(parcel, val);
if (!ret) {
ROSEN_LOGE("unirender: failed RSMarshallingHelper::Marshalling Drawing::DrawCmdList RecordCmd");
return ret;
if (!isRecordCmd) {
ret &= MarshallingRecordCmdFromDrawCmdList(parcel, val);
if (!ret) {
ROSEN_LOGE("unirender: failed RSMarshallingHelper::Marshalling Drawing::DrawCmdList RecordCmd");
return ret;
}
}
#ifdef ROSEN_OHOS
std::vector<std::shared_ptr<Drawing::SurfaceBufferEntry>> surfaceBufferEntryVec;
@ -1655,7 +1681,7 @@ bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Draw
return ret;
}
bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val)
bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val, bool isRecordCmd)
{
int32_t size = parcel.ReadInt32();
if (size == -1) {
@ -1744,7 +1770,7 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing:
bool ret = true;
uint32_t objectSize = parcel.ReadUint32();
if (objectSize > 0) {
if (objectSize > PARTICLE_UPPER_LIMIT) {
if (objectSize > Drawing::MAX_OPITEMSIZE) {
return false;
}
std::vector<std::shared_ptr<Drawing::ExtendImageObject>> imageObjectVec;
@ -1763,7 +1789,7 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing:
uint32_t objectBaseSize = parcel.ReadUint32();
if (objectBaseSize > 0) {
if (objectBaseSize > PARTICLE_UPPER_LIMIT) {
if (objectBaseSize > Drawing::MAX_OPITEMSIZE) {
return false;
}
std::vector<std::shared_ptr<Drawing::ExtendImageBaseObj>> ObjectBaseVec;
@ -1786,15 +1812,17 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing:
return ret;
}
ret &= UnmarshallingRecordCmdToDrawCmdList(parcel, val);
if (!ret) {
ROSEN_LOGE("unirender: failed RSMarshallingHelper::Marshalling Drawing::DrawCmdList RecordCmd");
return ret;
if (!isRecordCmd) {
ret &= UnmarshallingRecordCmdToDrawCmdList(parcel, val);
if (!ret) {
ROSEN_LOGE("unirender: failed RSMarshallingHelper::Marshalling Drawing::DrawCmdList RecordCmd");
return ret;
}
}
#ifdef ROSEN_OHOS
uint32_t surfaceBufferEntrySize = parcel.ReadUint32();
if (surfaceBufferEntrySize > 0) {
if (surfaceBufferEntrySize > PARTICLE_UPPER_LIMIT) {
if (surfaceBufferEntrySize > Drawing::MAX_OPITEMSIZE) {
return false;
}
std::vector<std::shared_ptr<Drawing::SurfaceBufferEntry>> surfaceBufferEntryVec;
@ -1834,7 +1862,7 @@ bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Draw
const auto& rect = val->GetCullRect();
return parcel.WriteFloat(rect.GetLeft()) && parcel.WriteFloat(rect.GetTop()) &&
parcel.WriteFloat(rect.GetRight()) && parcel.WriteFloat(rect.GetBottom()) &&
RSMarshallingHelper::Marshalling(parcel, val->GetDrawCmdList());
RSMarshallingHelper::Marshalling(parcel, val->GetDrawCmdList(), true);
}
bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::RecordCmd>& val)
@ -1851,7 +1879,7 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing:
return false;
}
std::shared_ptr<Drawing::DrawCmdList> drawCmdList = nullptr;
success = RSMarshallingHelper::Unmarshalling(parcel, drawCmdList);
success = RSMarshallingHelper::Unmarshalling(parcel, drawCmdList, true);
if (!success) {
ROSEN_LOGE("RSMarshallingHelper::Unmarshalling RecordCmd, drawCmdList unmarshalling failed.");
return false;

View File

@ -365,12 +365,13 @@ bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, RRectT<float>& val)
// Drawing::DrawCmdList
bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val)
bool RSMarshallingHelper::Marshalling(Parcel& parcel, const std::shared_ptr<Drawing::DrawCmdList>& val,
bool isRecordCmd)
{
return {};
}
bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val)
bool RSMarshallingHelper::Unmarshalling(Parcel& parcel, std::shared_ptr<Drawing::DrawCmdList>& val, bool isRecordCmd)
{
return {};
}