Backed out 4 changesets (bug 1688452) for assertion and bc failures on browser_translation_bing.js.

Backed out changeset 1a720cffc019 (bug 1688452)
Backed out changeset 797a7e243d43 (bug 1688452)
Backed out changeset 00fd325069fa (bug 1688452)
Backed out changeset 23ef68478e93 (bug 1688452)
This commit is contained in:
Cosmin Sabou
2021-09-29 20:13:33 +03:00
parent 040d0b4490
commit af572dd42f
14 changed files with 281 additions and 1051 deletions

View File

@@ -83,10 +83,6 @@
// our symbol names.
#include "expat_config.h"
#include "expat.h"
#include "rlbox_expat.h"
#ifdef MOZ_WASM_SANDBOXING_EXPAT
# include "mozilla/ipc/LibrarySandboxPreload.h"
#endif
extern "C" {
// Defined in intl/encoding_glue/src/lib.rs
@@ -535,69 +531,41 @@ void nsHtml5StreamParser::SetEncodingFromExpat(const char16_t* aEncoding) {
// Using a separate user data struct also avoids bloating nsHtml5StreamParser
// by one pointer.
struct UserData {
tainted_expat<XML_Parser> mExpat;
XML_Parser mExpat;
nsHtml5StreamParser* mStreamParser;
};
// Using no-namespace handler callbacks to avoid including expat.h in
// nsHtml5StreamParser.h, since doing so would cause naming conclicts.
static void HandleXMLDeclaration(rlbox_sandbox_expat& aSandbox,
tainted_expat<void*> /* aUserData */,
tainted_expat<const XML_Char*> /* aVersion */,
tainted_expat<const XML_Char*> t_aEncoding,
tainted_expat<int> /* aStandalone */) {
UserData* ud = static_cast<UserData*>(aSandbox.sandbox_storage);
MOZ_RELEASE_ASSERT(ud);
bool copied_encoding = false;
auto* encoding =
transfer_xmlstring_no_validate(aSandbox, t_aEncoding, copied_encoding);
// The attacker has control over the encoding. This could potentially lead to
// confusion/XSS attacks. We should try to restrict the encoding to something
// safe. Bug 1693991 tracks this.
static void HandleXMLDeclaration(void* aUserData, const XML_Char* aVersion,
const XML_Char* aEncoding, int aStandalone) {
UserData* ud = static_cast<UserData*>(aUserData);
ud->mStreamParser->SetEncodingFromExpat(
reinterpret_cast<const char16_t*>(encoding));
if (copied_encoding) {
free(encoding);
}
aSandbox.invoke_sandbox_function(MOZ_XML_StopParser, ud->mExpat, false);
reinterpret_cast<const char16_t*>(aEncoding));
XML_StopParser(ud->mExpat, false);
}
static void HandleStartElement(rlbox_sandbox_expat& aSandbox,
tainted_expat<void*> /* aUserData */,
tainted_expat<const XML_Char*> /* aName */,
tainted_expat<const XML_Char**> /*aAtts */) {
UserData* ud = static_cast<UserData*>(aSandbox.sandbox_storage);
MOZ_RELEASE_ASSERT(ud);
aSandbox.invoke_sandbox_function(MOZ_XML_StopParser, ud->mExpat, false);
static void HandleStartElement(void* aUserData, const XML_Char* aName,
const XML_Char** aAtts) {
UserData* ud = static_cast<UserData*>(aUserData);
XML_StopParser(ud->mExpat, false);
}
static void HandleEndElement(rlbox_sandbox_expat& aSandbox,
tainted_expat<void*> /* aUserData */,
tainted_expat<const XML_Char*> /* aName */) {
UserData* ud = static_cast<UserData*>(aSandbox.sandbox_storage);
MOZ_RELEASE_ASSERT(ud);
aSandbox.invoke_sandbox_function(MOZ_XML_StopParser, ud->mExpat, false);
static void HandleEndElement(void* aUserData, const XML_Char* aName) {
UserData* ud = static_cast<UserData*>(aUserData);
XML_StopParser(ud->mExpat, false);
}
static void HandleComment(rlbox_sandbox_expat& aSandbox,
tainted_expat<void*> /* aUserData */,
tainted_expat<const XML_Char*> /* aName */) {
UserData* ud = static_cast<UserData*>(aSandbox.sandbox_storage);
MOZ_RELEASE_ASSERT(ud);
aSandbox.invoke_sandbox_function(MOZ_XML_StopParser, ud->mExpat, false);
static void HandleComment(void* aUserData, const XML_Char* aName) {
UserData* ud = static_cast<UserData*>(aUserData);
XML_StopParser(ud->mExpat, false);
}
static void HandleProcessingInstruction(
rlbox_sandbox_expat& aSandbox, tainted_expat<void*> /* aUserData */,
tainted_expat<const XML_Char*> /* aTarget */,
tainted_expat<const XML_Char*> /* aData */) {
UserData* ud = static_cast<UserData*>(aSandbox.sandbox_storage);
MOZ_RELEASE_ASSERT(ud);
aSandbox.invoke_sandbox_function(MOZ_XML_StopParser, ud->mExpat, false);
static void HandleProcessingInstruction(void* aUserData,
const XML_Char* aTarget,
const XML_Char* aData) {
UserData* ud = static_cast<UserData*>(aUserData);
XML_StopParser(ud->mExpat, false);
}
void nsHtml5StreamParser::FinalizeSniffingWithDetector(
@@ -634,6 +602,10 @@ nsresult nsHtml5StreamParser::FinalizeSniffing(Span<const uint8_t> aFromSegment,
MOZ_ASSERT(mCharsetSource < kCharsetFromXmlDeclarationUtf16,
"Should not finalize sniffing with strong decision already made.");
if (mMode == VIEW_SOURCE_XML) {
static const XML_Memory_Handling_Suite memsuite = {
(void* (*)(size_t))moz_xmalloc, (void* (*)(void*, size_t))moz_xrealloc,
free};
static const char16_t kExpatSeparator[] = {0xFFFF, '\0'};
static const char16_t kISO88591[] = {'I', 'S', 'O', '-', '8', '8',
@@ -650,68 +622,12 @@ nsresult nsHtml5StreamParser::FinalizeSniffing(Span<const uint8_t> aFromSegment,
// and without triggering expat's unknown encoding code paths. This is
// enough to be able to use expat to parse the XML declaration in order
// to extract the encoding name from it.
// Create sandbox and set the thread local user data to ud
rlbox_sandbox_expat sandbox;
#ifdef MOZ_WASM_SANDBOXING_EXPAT
sandbox.create_sandbox(mozilla::ipc::GetSandboxedRLBoxPath().get());
#else
sandbox.create_sandbox();
#endif
sandbox.sandbox_storage = &ud;
tainted_expat<const XML_Memory_Handling_Suite*> t_memsuite = nullptr;
#ifndef MOZ_WASM_SANDBOXING_EXPAT
// In the noop sandbox we can use the moz allocator.
static const XML_Memory_Handling_Suite s_memsuite = {
(void* (*)(size_t))moz_xmalloc, (void* (*)(void*, size_t))moz_xrealloc,
free};
// Since the code running in a noop sandbox is not actually sandboxed, we
// can expose the memsuite directly using UNSAFE_accept_pointer. We don't
// want to convert these functions to callbacks that can be used when
// expat is actually in a memory isolated sandbox -- expat should use the
// sandbox-local memsuite.
t_memsuite = sandbox.UNSAFE_accept_pointer(&s_memsuite);
#endif
// We need to copy the encoding and namespace separator into the sandbox.
// For the noop sandbox we pass in the memsuite; for the Wasm sandbox, we
// pass in nullptr to let expat use the standard library memory suite.
bool copied_kExpatSeparator = false;
auto t_kExpatSeparator = rlbox::copy_memory_or_grant_access(
sandbox, kExpatSeparator, sizeof(kExpatSeparator), false,
copied_kExpatSeparator);
bool copied_kISO88591 = false;
auto t_kISO88591 = rlbox::copy_memory_or_grant_access(
sandbox, kISO88591, sizeof(kISO88591), false, copied_kISO88591);
ud.mExpat = sandbox.invoke_sandbox_function(
MOZ_XML_ParserCreate_MM,
rlbox::sandbox_const_cast<const char16_t*>(t_kISO88591), t_memsuite,
t_kExpatSeparator);
if (copied_kExpatSeparator) {
sandbox.free_in_sandbox(t_kExpatSeparator);
}
if (copied_kISO88591) {
sandbox.free_in_sandbox(t_kISO88591);
}
auto t_HandleXMLDeclaration =
sandbox.register_callback(HandleXMLDeclaration);
auto t_HandleStartElement = sandbox.register_callback(HandleStartElement);
auto t_HandleEndElement = sandbox.register_callback(HandleEndElement);
auto t_HandleComment = sandbox.register_callback(HandleComment);
auto t_HandleProcessingInstruction =
sandbox.register_callback(HandleProcessingInstruction);
sandbox.invoke_sandbox_function(MOZ_XML_SetXmlDeclHandler, ud.mExpat,
t_HandleXMLDeclaration);
sandbox.invoke_sandbox_function(MOZ_XML_SetElementHandler, ud.mExpat,
t_HandleStartElement, t_HandleEndElement);
sandbox.invoke_sandbox_function(MOZ_XML_SetCommentHandler, ud.mExpat,
t_HandleComment);
sandbox.invoke_sandbox_function(MOZ_XML_SetProcessingInstructionHandler,
ud.mExpat, t_HandleProcessingInstruction);
ud.mExpat = XML_ParserCreate_MM(kISO88591, &memsuite, kExpatSeparator);
XML_SetXmlDeclHandler(ud.mExpat, HandleXMLDeclaration);
XML_SetElementHandler(ud.mExpat, HandleStartElement, HandleEndElement);
XML_SetCommentHandler(ud.mExpat, HandleComment);
XML_SetProcessingInstructionHandler(ud.mExpat, HandleProcessingInstruction);
XML_SetUserData(ud.mExpat, static_cast<void*>(&ud));
XML_Status status = XML_STATUS_OK;
@@ -723,42 +639,16 @@ nsresult nsHtml5StreamParser::FinalizeSniffing(Span<const uint8_t> aFromSegment,
// 1024 bytes long or shorter). Thus, we parse both buffers, but if the
// first call succeeds already, we skip parsing the second buffer.
if (mSniffingBuffer) {
// copy (or transfer) mSniffingBuffer into the sandbox
bool copied_mSniffingBuffer = false;
auto t_mSniffingBuffer = rlbox::copy_memory_or_grant_access(
sandbox, reinterpret_cast<const char*>(mSniffingBuffer.get()),
mSniffingLength, false, copied_mSniffingBuffer);
status = sandbox
.invoke_sandbox_function(MOZ_XML_Parse, ud.mExpat,
t_mSniffingBuffer, mSniffingLength,
false)
.copy_and_verify(status_verifier);
if (copied_mSniffingBuffer) {
sandbox.free_in_sandbox(t_mSniffingBuffer);
}
status = XML_Parse(ud.mExpat,
reinterpret_cast<const char*>(mSniffingBuffer.get()),
mSniffingLength, false);
}
if (status == XML_STATUS_OK && mCharsetSource < kCharsetFromMetaTag) {
bool copied_aFromSegmentElements = false;
auto t_aFromSegmentElements = rlbox::copy_memory_or_grant_access(
sandbox, reinterpret_cast<const char*>(aFromSegment.Elements()),
aFromSegment.LengthBytes(), false, copied_aFromSegmentElements);
mozilla::Unused << sandbox
.invoke_sandbox_function(MOZ_XML_Parse, ud.mExpat,
t_aFromSegmentElements,
aCountToSniffingLimit,
false)
.copy_and_verify(status_verifier);
if (copied_aFromSegmentElements) {
sandbox.free_in_sandbox(t_aFromSegmentElements);
}
mozilla::Unused << XML_Parse(
ud.mExpat, reinterpret_cast<const char*>(aFromSegment.Elements()),
aCountToSniffingLimit, false);
}
sandbox.invoke_sandbox_function(MOZ_XML_ParserFree, ud.mExpat);
t_HandleXMLDeclaration.unregister();
t_HandleStartElement.unregister();
t_HandleEndElement.unregister();
t_HandleComment.unregister();
t_HandleProcessingInstruction.unregister();
sandbox.destroy_sandbox();
XML_ParserFree(ud.mExpat);
if (mCharsetSource < kCharsetFromMetaTag) {
// Failed to get an encoding from the XML declaration. XML defaults