- Apply more FF58 fixes except the following https://bugzilla.mozilla.org/buglist.cgi?bug_id=1281965,1379276,1382851,1390882,1396399,1412653,1413857,1415770,1415788,1416879,1418074,1418841,1418966,1420049,1421099,1421324,1426449 Changes: https://github.com/MrAlex94/Waterfox/compare/56.0.3...52216f01e1f3 Security: a891c5b4-3d7a-4de9-9c71-eef3fd698c77
244 lines
8.5 KiB
Text
244 lines
8.5 KiB
Text
commit 408a8eddca66
|
|
Author: Ted Campbell <tcampbell@mozilla.com>
|
|
Date: Tue Nov 28 22:52:34 2017 -0500
|
|
|
|
Bug 1418894 - Use marker values in XDR data to detect corruption. r=nbp a=gchang
|
|
|
|
MozReview-Commit-ID: D6PxPBdgtPP
|
|
|
|
--HG--
|
|
extra : source : 3c5cc7786d922c70b937d1dbe57f0ce700c39551
|
|
---
|
|
js/src/jsfun.cpp | 4 ++++
|
|
js/src/jsscript.cpp | 10 ++++++++++
|
|
js/src/vm/Xdr.h | 12 ++++++++++++
|
|
3 files changed, 26 insertions(+)
|
|
|
|
diff --git js/src/jsfun.cpp js/src/jsfun.cpp
|
|
index 234d0cc3438c..5a461c9230eb 100644
|
|
--- js/src/jsfun.cpp
|
|
+++ js/src/jsfun.cpp
|
|
@@ -682,6 +682,10 @@ js::XDRInterpretedFunction(XDRState<mode>* xdr, HandleScope enclosingScope,
|
|
objp.set(fun);
|
|
}
|
|
|
|
+ // Verify marker at end of function to detect buffer trunction.
|
|
+ if (!xdr->codeMarker(0x9E35CA1F))
|
|
+ return false;
|
|
+
|
|
return true;
|
|
}
|
|
|
|
diff --git js/src/jsscript.cpp js/src/jsscript.cpp
|
|
index 1b31a0639644..88d6c7bc75b6 100644
|
|
--- js/src/jsscript.cpp
|
|
+++ js/src/jsscript.cpp
|
|
@@ -808,6 +808,11 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
|
|
if (mode == XDR_DECODE)
|
|
vector[i].init(scope);
|
|
}
|
|
+
|
|
+ // Verify marker to detect data corruption after decoding scope data. A
|
|
+ // mismatch here indicates we will almost certainly crash in release.
|
|
+ if (!xdr->codeMarker(0x48922BAB))
|
|
+ return false;
|
|
}
|
|
|
|
/*
|
|
@@ -900,6 +905,11 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
|
|
}
|
|
}
|
|
|
|
+ // Verify marker to detect data corruption after decoding object data. A
|
|
+ // mismatch here indicates we will almost certainly crash in release.
|
|
+ if (!xdr->codeMarker(0xF83B989A))
|
|
+ return false;
|
|
+
|
|
if (ntrynotes != 0) {
|
|
JSTryNote* tnfirst = script->trynotes()->vector;
|
|
MOZ_ASSERT(script->trynotes()->length == ntrynotes);
|
|
diff --git js/src/vm/Xdr.h js/src/vm/Xdr.h
|
|
index 18fa1af8ab5b..0a6cbf01b50f 100644
|
|
--- js/src/vm/Xdr.h
|
|
+++ js/src/vm/Xdr.h
|
|
@@ -307,6 +307,18 @@ class XDRState : public XDRCoderBase
|
|
return true;
|
|
}
|
|
|
|
+ bool codeMarker(uint32_t magic) {
|
|
+ uint32_t actual = magic;
|
|
+ if (!codeUint32(&actual))
|
|
+ return false;
|
|
+ if (actual != magic) {
|
|
+ // Fail in debug, but only soft-fail in release
|
|
+ MOZ_ASSERT(false, "Bad XDR marker");
|
|
+ return fail(JS::TranscodeResult_Failure_BadDecode);
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
bool codeBytes(void* bytes, size_t len) {
|
|
if (len == 0)
|
|
return true;
|
|
|
|
commit 885c19e8e675
|
|
Author: Ted Campbell <tcampbell@mozilla.com>
|
|
Date: Tue Nov 28 23:01:49 2017 -0500
|
|
|
|
Bug 1418894 - Harden XDR data decoding. r=nbp a=gchang
|
|
|
|
This patch adds better error detection to XDR decoding to reduce memory
|
|
corruption in the event that XDR data is corrupt (which is not
|
|
*supposed* to happen).
|
|
|
|
Add missing default cases. Make out-of-range values fail the decode by
|
|
asserting in debug, and returning a TranscodeError in release. Mix a
|
|
magic value into enum value before transcoding to buffer (to reduce
|
|
chance of garbage data being decoded).
|
|
|
|
MozReview-Commit-ID: 1wPkho9dm8c
|
|
|
|
--HG--
|
|
extra : source : 484499ffcbbad636a904832cc90c56c016ad4582
|
|
---
|
|
js/src/jsapi.h | 2 +-
|
|
js/src/jsscript.cpp | 40 ++++++++++++++++++++++------------------
|
|
js/src/shell/js.cpp | 4 ++--
|
|
js/src/vm/Xdr.h | 8 ++++++--
|
|
4 files changed, 31 insertions(+), 23 deletions(-)
|
|
|
|
diff --git js/src/jsapi.h js/src/jsapi.h
|
|
index 323396025b7a..c43a4c693778 100644
|
|
--- js/src/jsapi.h
|
|
+++ js/src/jsapi.h
|
|
@@ -6420,7 +6420,7 @@ enum TranscodeResult
|
|
TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1,
|
|
TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2,
|
|
TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3,
|
|
- TranscodeResult_Failure_UnknownClassKind = TranscodeResult_Failure | 0x4,
|
|
+ TranscodeResult_Failure_BadDecode = TranscodeResult_Failure | 0x4,
|
|
TranscodeResult_Failure_WrongCompileOption = TranscodeResult_Failure | 0x5,
|
|
TranscodeResult_Failure_NotInterpretedFun = TranscodeResult_Failure | 0x6,
|
|
|
|
diff --git js/src/jsscript.cpp js/src/jsscript.cpp
|
|
index eff03d909353..1b31a0639644 100644
|
|
--- js/src/jsscript.cpp
|
|
+++ js/src/jsscript.cpp
|
|
@@ -92,24 +92,19 @@ js::XDRScriptConst(XDRState<mode>* xdr, MutableHandleValue vp)
|
|
{
|
|
JSContext* cx = xdr->cx();
|
|
|
|
- /*
|
|
- * A script constant can be an arbitrary primitive value as they are used
|
|
- * to implement JSOP_LOOKUPSWITCH. But they cannot be objects, see
|
|
- * bug 407186.
|
|
- */
|
|
enum ConstTag {
|
|
- SCRIPT_INT = 0,
|
|
- SCRIPT_DOUBLE = 1,
|
|
- SCRIPT_ATOM = 2,
|
|
- SCRIPT_TRUE = 3,
|
|
- SCRIPT_FALSE = 4,
|
|
- SCRIPT_NULL = 5,
|
|
- SCRIPT_OBJECT = 6,
|
|
- SCRIPT_VOID = 7,
|
|
- SCRIPT_HOLE = 8
|
|
+ SCRIPT_INT,
|
|
+ SCRIPT_DOUBLE,
|
|
+ SCRIPT_ATOM,
|
|
+ SCRIPT_TRUE,
|
|
+ SCRIPT_FALSE,
|
|
+ SCRIPT_NULL,
|
|
+ SCRIPT_OBJECT,
|
|
+ SCRIPT_VOID,
|
|
+ SCRIPT_HOLE
|
|
};
|
|
|
|
- uint32_t tag;
|
|
+ ConstTag tag;
|
|
if (mode == XDR_ENCODE) {
|
|
if (vp.isInt32()) {
|
|
tag = SCRIPT_INT;
|
|
@@ -133,7 +128,7 @@ js::XDRScriptConst(XDRState<mode>* xdr, MutableHandleValue vp)
|
|
}
|
|
}
|
|
|
|
- if (!xdr->codeUint32(&tag))
|
|
+ if (!xdr->codeEnum32(&tag))
|
|
return false;
|
|
|
|
switch (tag) {
|
|
@@ -199,6 +194,10 @@ js::XDRScriptConst(XDRState<mode>* xdr, MutableHandleValue vp)
|
|
if (mode == XDR_DECODE)
|
|
vp.setMagic(JS_ELEMENTS_HOLE);
|
|
break;
|
|
+ default:
|
|
+ // Fail in debug, but only soft-fail in release
|
|
+ MOZ_ASSERT(false, "Bad XDR value kind");
|
|
+ return xdr->fail(JS::TranscodeResult_Failure_BadDecode);
|
|
}
|
|
return true;
|
|
}
|
|
@@ -800,6 +799,10 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
|
|
case ScopeKind::WasmFunction:
|
|
MOZ_CRASH("wasm functions cannot be nested in JSScripts");
|
|
break;
|
|
+ default:
|
|
+ // Fail in debug, but only soft-fail in release
|
|
+ MOZ_ASSERT(false, "Bad XDR scope kind");
|
|
+ return xdr->fail(JS::TranscodeResult_Failure_BadDecode);
|
|
}
|
|
|
|
if (mode == XDR_DECODE)
|
|
@@ -890,8 +893,9 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
|
|
}
|
|
|
|
default: {
|
|
- MOZ_ASSERT(false, "Unknown class kind.");
|
|
- return xdr->fail(JS::TranscodeResult_Failure_UnknownClassKind);
|
|
+ // Fail in debug, but only soft-fail in release
|
|
+ MOZ_ASSERT(false, "Bad XDR class kind");
|
|
+ return xdr->fail(JS::TranscodeResult_Failure_BadDecode);
|
|
}
|
|
}
|
|
}
|
|
diff --git js/src/shell/js.cpp js/src/shell/js.cpp
|
|
index 16ee93bc66a8..1f5afb04e1f8 100644
|
|
--- js/src/shell/js.cpp
|
|
+++ js/src/shell/js.cpp
|
|
@@ -1519,9 +1519,9 @@ ConvertTranscodeResultToJSException(JSContext* cx, JS::TranscodeResult rv)
|
|
MOZ_ASSERT(!cx->isExceptionPending());
|
|
JS_ReportErrorASCII(cx, "Asm.js is not supported by XDR");
|
|
return false;
|
|
- case JS::TranscodeResult_Failure_UnknownClassKind:
|
|
+ case JS::TranscodeResult_Failure_BadDecode:
|
|
MOZ_ASSERT(!cx->isExceptionPending());
|
|
- JS_ReportErrorASCII(cx, "Unknown class kind, go fix it.");
|
|
+ JS_ReportErrorASCII(cx, "XDR data corruption");
|
|
return false;
|
|
case JS::TranscodeResult_Failure_WrongCompileOption:
|
|
MOZ_ASSERT(!cx->isExceptionPending());
|
|
diff --git js/src/vm/Xdr.h js/src/vm/Xdr.h
|
|
index e88968b9a4c0..18fa1af8ab5b 100644
|
|
--- js/src/vm/Xdr.h
|
|
+++ js/src/vm/Xdr.h
|
|
@@ -279,13 +279,17 @@ class XDRState : public XDRCoderBase
|
|
template <typename T>
|
|
bool codeEnum32(T* val, typename mozilla::EnableIf<mozilla::IsEnum<T>::value, T>::Type * = NULL)
|
|
{
|
|
+ // Mix the enumeration value with a random magic number, such that a
|
|
+ // corruption with a low-ranged value (like 0) is less likely to cause a
|
|
+ // miss-interpretation of the XDR content and instead cause a failure.
|
|
+ const uint32_t MAGIC = 0x21AB218C;
|
|
uint32_t tmp;
|
|
if (mode == XDR_ENCODE)
|
|
- tmp = uint32_t(*val);
|
|
+ tmp = uint32_t(*val) ^ MAGIC;
|
|
if (!codeUint32(&tmp))
|
|
return false;
|
|
if (mode == XDR_DECODE)
|
|
- *val = T(tmp);
|
|
+ *val = T(tmp ^ MAGIC);
|
|
return true;
|
|
}
|
|
|