已合并
CVE-2026-17914 #2375
Oliver创建于 8月11日
CVE-2026-17914 #2375
已合并
共 1 个文件变更+29-8
| @@ -4,13 +4,16 @@ | |||
| 4 | * Use of this source code is governed by a BSD-style license that can be | 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. | 5 | * found in the LICENSE file. |
| 6 | */ | 6 | */ |
| 7 | +#include "src/xml/SkXMLParser.h" | ||
| 7 | 8 | ||
| 8 | #include "include/core/SkStream.h" | 9 | #include "include/core/SkStream.h" |
| 9 | #include "include/core/SkString.h" | 10 | #include "include/core/SkString.h" |
| 10 | #include "include/core/SkTypes.h" | 11 | #include "include/core/SkTypes.h" |
| 11 | #include "include/private/base/SkTemplates.h" | 12 | #include "include/private/base/SkTemplates.h" |
| 12 | #include "include/private/base/SkTo.h" | 13 | #include "include/private/base/SkTo.h" |
| 13 | -#include "src/xml/SkXMLParser.h" | 14 | +#include "src/base/SkRandom.h" |
| 15 | +#include "src/base/SkTime.h" | ||
| 16 | +#include "src/base/SkUtils.h" | ||
| 14 | 17 | ||
| 15 | #include <expat.h> | 18 | #include <expat.h> |
| 16 | 19 | ||
| @@ -59,7 +62,24 @@ void SkXMLParserError::reset() { | |||
| 59 | 62 | ||
| 60 | namespace { | 63 | namespace { |
| 61 | 64 | ||
| 62 | -constexpr const void* kHashSeed = &kHashSeed; | 65 | +// Return a random number based on the clock to be consistent |
| 66 | +// across platforms yet hard to guess and not leaking information. | ||
| 67 | +static uint32_t get_hash_salt() { | ||
| 68 | + static const uint32_t s_salt = []() { | ||
| 69 | + double nsecs = SkTime::GetNSecs(); | ||
| 70 | + uint64_t timeVal = sk_bit_cast<uint64_t>(nsecs); | ||
| 71 | + uint32_t seed = static_cast<uint32_t>(timeVal ^ timeVal >> 32); | ||
| 72 | + | ||
| 73 | + SkRandom rand(seed); | ||
| 74 | + uint32_t salt = rand.nextU(); | ||
| 75 | + while (salt == 0) [[unlikely]] { | ||
| 76 | + // Expat hash seed must be non-zero or the default cPRNG will be used. | ||
| 77 | + salt = rand.nextU(); | ||
| 78 | + } | ||
| 79 | + return salt; | ||
| 80 | + }(); | ||
| 81 | + return s_salt; | ||
| 82 | +} | ||
| 63 | 83 | ||
| 64 | const XML_Memory_Handling_Suite sk_XML_alloc = { | 84 | const XML_Memory_Handling_Suite sk_XML_alloc = { |
| 65 | sk_malloc_throw, | 85 | sk_malloc_throw, |
| @@ -149,12 +169,13 @@ bool SkXMLParser::parse(SkStream& docStream) | |||
| 149 | return false; | 169 | return false; |
| 150 | } | 170 | } |
| 151 | 171 | ||
| 152 | - // Avoid calls to rand_s if this is not set. This seed helps prevent DOS | 172 | + // Expat calls to rand_s if no salt is set, which is not allowed on Windows. |
| 153 | - // with a known hash sequence so an address is sufficient. The provided | 173 | + // https://crbug.com/40088338 |
| 154 | - // seed should not be zero as that results in a call to rand_s. | 174 | + // Setting the salt helps prevent DOS with a known hash sequence. Generating a |
| 155 | - unsigned long seed = static_cast<unsigned long>( | 175 | + // random salt once per process oursevles ensures the salt is non-deterministic |
| 156 | - reinterpret_cast<size_t>(kHashSeed) & 0xFFFFFFFF); | 176 | + // and unguessable, while preventing calls to rand_s inside sandboxed processes |
| 157 | - XML_SetHashSalt(ctx.fXMLParser, seed ? seed : 1); | 177 | + // on Windows. |
| 178 | + XML_SetHashSalt(ctx.fXMLParser, get_hash_salt()); | ||
| 158 | 179 | ||
| 159 | XML_SetUserData(ctx.fXMLParser, &ctx); | 180 | XML_SetUserData(ctx.fXMLParser, &ctx); |
| 160 | XML_SetElementHandler(ctx.fXMLParser, start_element_handler, end_element_handler); | 181 | XML_SetElementHandler(ctx.fXMLParser, start_element_handler, end_element_handler); |