已开启
漏洞修复 #9359
zzs911创建于 14 天前
漏洞修复 #9359
已开启
共 5 个文件变更+80-19
| @@ -1067,8 +1067,12 @@ void DashMpdParser::ParseMPD(const char *mpdData, uint32_t length) | |||
| 1067 | 1067 | ||
| 1068 | std::shared_ptr<XmlParser> xmlParser = std::make_shared<XmlParser>(); | 1068 | std::shared_ptr<XmlParser> xmlParser = std::make_shared<XmlParser>(); |
| 1069 | int32_t ret = xmlParser->ParseFromBuffer(mpdData, length); | 1069 | int32_t ret = xmlParser->ParseFromBuffer(mpdData, length); |
| 1070 | + if (ret != static_cast<int32_t>(XmlBaseRtnValue::XML_BASE_OK)) { | ||
| 1071 | + MEDIA_LOG_E("Parse error or stop " PUBLIC_LOG_D32 ", ret=" PUBLIC_LOG_D32, this->stopFlag_, ret); | ||
| 1072 | + return; | ||
| 1073 | + } | ||
| 1070 | std::shared_ptr<XmlElement> rootElement = xmlParser->GetRootElement(); | 1074 | std::shared_ptr<XmlElement> rootElement = xmlParser->GetRootElement(); |
| 1071 | - if (ret != static_cast<int32_t>(XmlBaseRtnValue::XML_BASE_OK) || this->stopFlag_ || rootElement == nullptr) { | 1075 | + if (this->stopFlag_ || rootElement == nullptr) { |
| 1072 | MEDIA_LOG_E("Parse error or stop " PUBLIC_LOG_D32 ", ret=" PUBLIC_LOG_D32, this->stopFlag_, ret); | 1076 | MEDIA_LOG_E("Parse error or stop " PUBLIC_LOG_D32 ", ret=" PUBLIC_LOG_D32, this->stopFlag_, ret); |
| 1073 | return; | 1077 | return; |
| 1074 | } | 1078 | } |
| @@ -55,6 +55,33 @@ SidxBoxParser::~SidxBoxParser() | |||
| 55 | MEDIA_LOG_D("SidxBoxParser deleter was called!!!!"); | 55 | MEDIA_LOG_D("SidxBoxParser deleter was called!!!!"); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | +template <typename T> bool GetBytes(char *buffer, uint32_t &currPos, uint32_t streamSize, T ¤tReturnValue) | ||
| 59 | +{ | ||
| 60 | + if constexpr (std::is_same_v<T, uint32_t>) { | ||
| 61 | + if (streamSize > currPos && streamSize - currPos >= SHIFT_NUM_4) { | ||
| 62 | + currentReturnValue = Get4Bytes(buffer, currPos); | ||
| 63 | + return true; | ||
| 64 | + } else { | ||
| 65 | + return false; | ||
| 66 | + } | ||
| 67 | + } else if constexpr (std::is_same_v<T, int64_t>) { | ||
| 68 | + if (streamSize > currPos && streamSize - currPos >= SHIFT_NUM_8) { | ||
| 69 | + currentReturnValue = Get8Bytes(buffer, currPos); | ||
| 70 | + return true; | ||
| 71 | + } else { | ||
| 72 | + return false; | ||
| 73 | + } | ||
| 74 | + } else if constexpr (std::is_same_v<T, unsigned short>) { | ||
| 75 | + if (streamSize > currPos && streamSize - currPos >= SHIFT_NUM_2) { | ||
| 76 | + currentReturnValue = Get2Bytes(buffer, currPos); | ||
| 77 | + return true; | ||
| 78 | + } else { | ||
| 79 | + return false; | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + return false; | ||
| 83 | +} | ||
| 84 | + | ||
| 58 | int32_t SidxBoxParser::ParseSidxBox(char *bitStream, uint32_t streamSize, int64_t sidxEndOffset, | 85 | int32_t SidxBoxParser::ParseSidxBox(char *bitStream, uint32_t streamSize, int64_t sidxEndOffset, |
| 59 | DashList<std::shared_ptr<SubSegmentIndex>> &subSegIndexTable) | 86 | DashList<std::shared_ptr<SubSegmentIndex>> &subSegIndexTable) |
| 60 | { | 87 | { |
| @@ -62,8 +89,15 @@ int32_t SidxBoxParser::ParseSidxBox(char *bitStream, uint32_t streamSize, int64_ | |||
| 62 | uint32_t currPos = 0; | 89 | uint32_t currPos = 0; |
| 63 | 90 | ||
| 64 | while (streamSize > currPos && BASE_BOX_HEAD_SIZE < streamSize - currPos) { | 91 | while (streamSize > currPos && BASE_BOX_HEAD_SIZE < streamSize - currPos) { |
| 65 | - Get4Bytes(bitStream, currPos); | 92 | + uint32_t boxType = 0; |
| 66 | - uint32_t boxType = Get4Bytes(bitStream, currPos); | 93 | + uint32_t dummyByte4 = 0; |
| 94 | + | ||
| 95 | + bool isByteReadSuccess = GetBytes<uint32_t>(bitStream, currPos, streamSize, dummyByte4); | ||
| 96 | + if (!isByteReadSuccess) return -1; | ||
| 97 | + | ||
| 98 | + isByteReadSuccess = GetBytes<uint32_t>(bitStream, currPos, streamSize, boxType); | ||
| 99 | + if (!isByteReadSuccess) return -1; | ||
| 100 | + | ||
| 67 | if (boxType == BEM_SIDX) { | 101 | if (boxType == BEM_SIDX) { |
| 68 | MEDIA_LOG_D("it is a sidx box"); | 102 | MEDIA_LOG_D("it is a sidx box"); |
| 69 | if (!BuildSubSegmentIndexes(bitStream, streamSize, sidxEndOffset, subSegIndexTable, currPos)) { | 103 | if (!BuildSubSegmentIndexes(bitStream, streamSize, sidxEndOffset, subSegIndexTable, currPos)) { |
| @@ -84,22 +118,31 @@ bool SidxBoxParser::BuildSubSegmentIndexes(char *bitStream, uint32_t streamSize, | |||
| 84 | DashList<std::shared_ptr<SubSegmentIndex>> &subSegIndexTable, | 118 | DashList<std::shared_ptr<SubSegmentIndex>> &subSegIndexTable, |
| 85 | uint32_t &currPos) | 119 | uint32_t &currPos) |
| 86 | { | 120 | { |
| 87 | - uint32_t vFlag = Get4Bytes(bitStream, currPos); | 121 | + uint32_t vFlag = 0; |
| 122 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, vFlag)) return false; | ||
| 123 | + | ||
| 88 | uint32_t version = GetVersion(vFlag); | 124 | uint32_t version = GetVersion(vFlag); |
| 89 | 125 | ||
| 90 | - Get4Bytes(bitStream, currPos); | 126 | + uint32_t dummyByte4 = 0; |
| 91 | - uint32_t timescale = Get4Bytes(bitStream, currPos); | 127 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, dummyByte4)) return false; |
| 128 | + | ||
| 129 | + uint32_t timescale = 0; | ||
| 130 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, timescale)) return false; | ||
| 92 | 131 | ||
| 93 | int64_t firstOffset; | 132 | int64_t firstOffset; |
| 94 | - | 133 | + int64_t dummyByte8 = 0; |
| 95 | if (version == 0) { | 134 | if (version == 0) { |
| 96 | // skip earliestPresentationTime | 135 | // skip earliestPresentationTime |
| 97 | - Get4Bytes(bitStream, currPos); | 136 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, dummyByte4)) return false; |
| 98 | - firstOffset = Get4Bytes(bitStream, currPos); | 137 | + |
| 138 | + uint32_t firstOffset32 = 0; | ||
| 139 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, firstOffset32)) return false; | ||
| 140 | + firstOffset = firstOffset32; | ||
| 99 | } else { | 141 | } else { |
| 100 | // skip earliestPresentationTime | 142 | // skip earliestPresentationTime |
| 101 | - Get8Bytes(bitStream, currPos); | 143 | + if (!GetBytes<int64_t>(bitStream, currPos, streamSize, dummyByte8)) return false; |
| 102 | - firstOffset = Get8Bytes(bitStream, currPos); | 144 | + |
| 145 | + if (!GetBytes<int64_t>(bitStream, currPos, streamSize, firstOffset)) return false; | ||
| 103 | } | 146 | } |
| 104 | 147 | ||
| 105 | // In the file containing the Segment Index box, the anchor point for a Segment Index box is the first byte | 148 | // In the file containing the Segment Index box, the anchor point for a Segment Index box is the first byte |
| @@ -109,7 +152,11 @@ bool SidxBoxParser::BuildSubSegmentIndexes(char *bitStream, uint32_t streamSize, | |||
| 109 | // skip reserved | 152 | // skip reserved |
| 110 | ForwardBytes(currPos, SHIFT_NUM_2); | 153 | ForwardBytes(currPos, SHIFT_NUM_2); |
| 111 | 154 | ||
| 112 | - uint32_t referenceCount = Get2Bytes(bitStream, currPos); | 155 | + uint32_t referenceCount = 0; |
| 156 | + unsigned short referenceCountShort = 0; | ||
| 157 | + if (!GetBytes<unsigned short>(bitStream, currPos, streamSize, referenceCountShort)) return false; | ||
| 158 | + referenceCount = referenceCountShort; | ||
| 159 | + | ||
| 113 | if ((referenceCount * SIDX_REFERENCE_ITEM_SIZE + currPos) > streamSize) { | 160 | if ((referenceCount * SIDX_REFERENCE_ITEM_SIZE + currPos) > streamSize) { |
| 114 | MEDIA_LOG_W("sidx box reference count error: " PUBLIC_LOG_U32 ", currPos:" PUBLIC_LOG_U32 ", streamSize:" | 161 | MEDIA_LOG_W("sidx box reference count error: " PUBLIC_LOG_U32 ", currPos:" PUBLIC_LOG_U32 ", streamSize:" |
| 115 | PUBLIC_LOG_U32, referenceCount, currPos, streamSize); | 162 | PUBLIC_LOG_U32, referenceCount, currPos, streamSize); |
| @@ -119,15 +166,17 @@ bool SidxBoxParser::BuildSubSegmentIndexes(char *bitStream, uint32_t streamSize, | |||
| 119 | MEDIA_LOG_D("sidx box reference count " PUBLIC_LOG_U32, referenceCount); | 166 | MEDIA_LOG_D("sidx box reference count " PUBLIC_LOG_U32, referenceCount); |
| 120 | for (uint32_t i = 0; i < referenceCount; i++) { | 167 | for (uint32_t i = 0; i < referenceCount; i++) { |
| 121 | std::shared_ptr<SubSegmentIndex> subSegIndex = std::make_shared<SubSegmentIndex>(); | 168 | std::shared_ptr<SubSegmentIndex> subSegIndex = std::make_shared<SubSegmentIndex>(); |
| 122 | - uint32_t typeAndSize = Get4Bytes(bitStream, currPos); | 169 | + uint32_t typeAndSize = 0; |
| 170 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, typeAndSize)) return false; | ||
| 123 | subSegIndex->referenceType_ = static_cast<int32_t>(GetReferenceType(typeAndSize)); | 171 | subSegIndex->referenceType_ = static_cast<int32_t>(GetReferenceType(typeAndSize)); |
| 124 | subSegIndex->referencedSize_ = static_cast<int32_t>(GetReferenceSize(typeAndSize)); | 172 | subSegIndex->referencedSize_ = static_cast<int32_t>(GetReferenceSize(typeAndSize)); |
| 125 | subSegIndex->startPos_ = mediaSegOffset; | 173 | subSegIndex->startPos_ = mediaSegOffset; |
| 126 | subSegIndex->endPos_ = mediaSegOffset + subSegIndex->referencedSize_ - 1; | 174 | subSegIndex->endPos_ = mediaSegOffset + subSegIndex->referencedSize_ - 1; |
| 127 | mediaSegOffset = subSegIndex->endPos_ + 1; | 175 | mediaSegOffset = subSegIndex->endPos_ + 1; |
| 128 | - subSegIndex->duration_ = Get4Bytes(bitStream, currPos); | 176 | + subSegIndex->duration_ = 0; |
| 177 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, subSegIndex->duration_)) return false; | ||
| 129 | subSegIndex->timeScale_ = timescale; | 178 | subSegIndex->timeScale_ = timescale; |
| 130 | - Get4Bytes(bitStream, currPos); // uint32_t sapInfo | 179 | + if (!GetBytes<uint32_t>(bitStream, currPos, streamSize, dummyByte4)) return false; // uint32_t sapInfo |
| 131 | subSegIndexTable.push_back(subSegIndex); | 180 | subSegIndexTable.push_back(subSegIndex); |
| 132 | } | 181 | } |
| 133 | return true; | 182 | return true; |
| @@ -270,13 +270,17 @@ void M3U8::UpdateDownloadFinished(const std::string& url, const std::string& loc | |||
| 270 | 270 | ||
| 271 | uint32_t M3U8::SaveMapData(uint8_t* data, uint32_t len, bool notBlock) | 271 | uint32_t M3U8::SaveMapData(uint8_t* data, uint32_t len, bool notBlock) |
| 272 | { | 272 | { |
| 273 | + FALSE_RETURN_V(data != nullptr, 0); | ||
| 273 | if (fmp4Header_ == nullptr && downloadHeaderRequest_) { | 274 | if (fmp4Header_ == nullptr && downloadHeaderRequest_) { |
| 274 | uint32_t headerLen = downloadHeaderRequest_->GetFileContentLengthNoWait(); | 275 | uint32_t headerLen = downloadHeaderRequest_->GetFileContentLengthNoWait(); |
| 275 | headerLen = headerLen > 0 ? headerLen : DEFAULT_HEADER_SIZE; // 1MB | 276 | headerLen = headerLen > 0 ? headerLen : DEFAULT_HEADER_SIZE; // 1MB |
| 276 | - fmp4Header_ = new uint8_t[headerLen]; | 277 | + headerLen = std::min(headerLen, DEFAULT_MAX_SIZE); |
| 278 | + fmp4Header_ = new(std::nothrow) uint8_t[headerLen]; | ||
| 279 | + FALSE_RETURN_V_MSG(fmp4Header_ != nullptr, 0u, "SaveMapData error, no memory."); | ||
| 280 | + fmp4HeaderLen = headerLen; | ||
| 277 | } | 281 | } |
| 278 | - NZERO_RETURN_V(memcpy_s(fmp4Header_ + downloadHeaderLen_, len, data, len), 0); | 282 | + NZERO_RETURN_V(memcpy_s(fmp4Header_ + downloadHeaderLen_, fmp4HeaderLen - downloadHeaderLen_, data, len), 0); |
| 279 | - downloadHeaderLen_ += len; | 283 | + downloadHeaderLen_ += std::min(len, fmp4HeaderLen - downloadHeaderLen_); |
| 280 | return len; | 284 | return len; |
| 281 | } | 285 | } |
| 282 | 286 | ||
| @@ -24,6 +24,10 @@ namespace OHOS { | |||
| 24 | namespace Media { | 24 | namespace Media { |
| 25 | namespace Plugins { | 25 | namespace Plugins { |
| 26 | namespace HttpPlugin { | 26 | namespace HttpPlugin { |
| 27 | +XmlParser::~XmlParser() | ||
| 28 | +{ | ||
| 29 | + DestroyDoc(); | ||
| 30 | +} | ||
| 27 | int32_t XmlParser::ParseFromBuffer(const char *buf, int32_t length) | 31 | int32_t XmlParser::ParseFromBuffer(const char *buf, int32_t length) |
| 28 | { | 32 | { |
| 29 | if (buf == nullptr || length == 0) { | 33 | if (buf == nullptr || length == 0) { |
| @@ -28,7 +28,7 @@ namespace HttpPlugin { | |||
| 28 | class XmlParser { | 28 | class XmlParser { |
| 29 | public: | 29 | public: |
| 30 | XmlParser() = default; | 30 | XmlParser() = default; |
| 31 | - ~XmlParser() = default; | 31 | + ~XmlParser(); |
| 32 | 32 | ||
| 33 | int32_t ParseFromBuffer(const char *buf, int32_t length); | 33 | int32_t ParseFromBuffer(const char *buf, int32_t length); |
| 34 | int32_t ParseFromString(const std::string &xmlStr); | 34 | int32_t ParseFromString(const std::string &xmlStr); |