fix cves
This commit is contained in:
parent
60f67e1c86
commit
3d3d4358d9
51
CVE-2020-15969.patch
Normal file
51
CVE-2020-15969.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Dan Minor <dminor@mozilla.com>
|
||||||
|
# Date 1600897949 0
|
||||||
|
# Wed Sep 23 21:52:29 2020 +0000
|
||||||
|
# Node ID ed2a659e965f27943d9b0c15d6e78d14e1ce9cb2
|
||||||
|
# Parent 7b2de9e57a768d949b569ac83fe5d58147e731b5
|
||||||
|
Bug 1666570 - Cherrypick ffed0925f27d404173c1e3e750d818f432d2c019 from usrsctp; r=drno
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D91047
|
||||||
|
|
||||||
|
diff -r 7b2de9e57a76 -r ed2a659e965f netwerk/sctp/src/netinet/sctp_indata.c
|
||||||
|
--- a/netwerk/sctp/src/netinet/sctp_indata.c Wed Sep 23 19:42:19 2020 +0000
|
||||||
|
+++ b/netwerk/sctp/src/netinet/sctp_indata.c Wed Sep 23 21:52:29 2020 +0000
|
||||||
|
@@ -1664,6 +1664,7 @@ sctp_process_a_data_chunk(struct sctp_tc
|
||||||
|
/* Process a data chunk */
|
||||||
|
/* struct sctp_tmit_chunk *chk; */
|
||||||
|
struct sctp_tmit_chunk *chk;
|
||||||
|
+ struct sctp_stream_in *strm;
|
||||||
|
uint32_t tsn, fsn, gap, mid;
|
||||||
|
struct mbuf *dmbuf;
|
||||||
|
int the_len;
|
||||||
|
@@ -2296,12 +2297,13 @@ finish_express_del:
|
||||||
|
/* All can be removed */
|
||||||
|
TAILQ_FOREACH_SAFE(control, &asoc->pending_reply_queue, next, ncontrol) {
|
||||||
|
TAILQ_REMOVE(&asoc->pending_reply_queue, control, next);
|
||||||
|
+ strm = &asoc->strmin[control->sinfo_stream];
|
||||||
|
sctp_queue_data_to_stream(stcb, asoc, control, abort_flag, &need_reasm_check);
|
||||||
|
if (*abort_flag) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (need_reasm_check) {
|
||||||
|
- (void)sctp_deliver_reasm_check(stcb, asoc, &asoc->strmin[control->sinfo_stream], SCTP_READ_LOCK_NOT_HELD);
|
||||||
|
+ (void)sctp_deliver_reasm_check(stcb, asoc, strm, SCTP_READ_LOCK_NOT_HELD);
|
||||||
|
need_reasm_check = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2316,12 +2318,13 @@ finish_express_del:
|
||||||
|
* control->sinfo_tsn > liste->tsn
|
||||||
|
*/
|
||||||
|
TAILQ_REMOVE(&asoc->pending_reply_queue, control, next);
|
||||||
|
+ strm = &asoc->strmin[control->sinfo_stream];
|
||||||
|
sctp_queue_data_to_stream(stcb, asoc, control, abort_flag, &need_reasm_check);
|
||||||
|
if (*abort_flag) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (need_reasm_check) {
|
||||||
|
- (void)sctp_deliver_reasm_check(stcb, asoc, &asoc->strmin[control->sinfo_stream], SCTP_READ_LOCK_NOT_HELD);
|
||||||
|
+ (void)sctp_deliver_reasm_check(stcb, asoc, strm, SCTP_READ_LOCK_NOT_HELD);
|
||||||
|
need_reasm_check = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
CVE-2020-15999.patch
Normal file
45
CVE-2020-15999.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Werner Lemberg <wl@gnu.org>
|
||||||
|
# Date 1603223819 0
|
||||||
|
# Tue Oct 20 19:56:59 2020 +0000
|
||||||
|
# Node ID 5c356dd9b0f31f612ce90b1f35b14d8cdb0b4ecb
|
||||||
|
# Parent a2ed93bf78d53309eb234b72ce0bf60ad93a3ac3
|
||||||
|
Bug 1672223 - [sfnt] Fix heap buffer overflow. r=jfkthame
|
||||||
|
|
||||||
|
This is CVE-2020-15999.
|
||||||
|
|
||||||
|
* src/sfnt/pngshim.c (Load_SBit_Png): Test bitmap size earlier.
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D94153
|
||||||
|
|
||||||
|
diff -r a2ed93bf78d5 -r 5c356dd9b0f3 modules/freetype2/src/sfnt/pngshim.c
|
||||||
|
--- a/modules/freetype2/src/sfnt/pngshim.c Tue Oct 20 21:14:51 2020 +0000
|
||||||
|
+++ b/modules/freetype2/src/sfnt/pngshim.c Tue Oct 20 19:56:59 2020 +0000
|
||||||
|
@@ -328,6 +328,13 @@
|
||||||
|
|
||||||
|
if ( populate_map_and_metrics )
|
||||||
|
{
|
||||||
|
+ /* reject too large bitmaps similarly to the rasterizer */
|
||||||
|
+ if ( imgHeight > 0x7FFF || imgWidth > 0x7FFF )
|
||||||
|
+ {
|
||||||
|
+ error = FT_THROW( Array_Too_Large );
|
||||||
|
+ goto DestroyExit;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
metrics->width = (FT_UShort)imgWidth;
|
||||||
|
metrics->height = (FT_UShort)imgHeight;
|
||||||
|
|
||||||
|
@@ -336,13 +343,6 @@
|
||||||
|
map->pixel_mode = FT_PIXEL_MODE_BGRA;
|
||||||
|
map->pitch = (int)( map->width * 4 );
|
||||||
|
map->num_grays = 256;
|
||||||
|
-
|
||||||
|
- /* reject too large bitmaps similarly to the rasterizer */
|
||||||
|
- if ( map->rows > 0x7FFF || map->width > 0x7FFF )
|
||||||
|
- {
|
||||||
|
- error = FT_THROW( Array_Too_Large );
|
||||||
|
- goto DestroyExit;
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert palette/gray image to rgb */
|
||||||
406
CVE-2020-16012.patch
Normal file
406
CVE-2020-16012.patch
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Lee Salzman <lsalzman@mozilla.com>
|
||||||
|
# Date 1601995009 0
|
||||||
|
# Tue Oct 06 14:36:49 2020 +0000
|
||||||
|
# Node ID 48c0f5033c286bd515b6f16e0905ff4ca94faf98
|
||||||
|
# Parent 5bc02423412647e3ee9a0681b38e418a10901601
|
||||||
|
Bug 1642028 - cherry-pick Skia blitting cleanups. r=jrmuizel
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D92476
|
||||||
|
|
||||||
|
diff -r 5bc024234126 -r 48c0f5033c28 gfx/skia/skia/src/opts/SkBlitRow_opts.h
|
||||||
|
--- a/gfx/skia/skia/src/opts/SkBlitRow_opts.h Tue Oct 06 16:58:11 2020 +0000
|
||||||
|
+++ b/gfx/skia/skia/src/opts/SkBlitRow_opts.h Tue Oct 06 14:36:49 2020 +0000
|
||||||
|
@@ -58,37 +58,114 @@
|
||||||
|
|
||||||
|
return _mm256_add_epi32(src, _mm256_or_si256(rb, ga));
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
-#elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
|
||||||
|
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
|
||||||
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
static inline __m128i SkPMSrcOver_SSE2(const __m128i& src, const __m128i& dst) {
|
||||||
|
- auto SkAlphaMulQ_SSE2 = [](const __m128i& c, const __m128i& scale) {
|
||||||
|
- const __m128i mask = _mm_set1_epi32(0xFF00FF);
|
||||||
|
- __m128i s = _mm_or_si128(_mm_slli_epi32(scale, 16), scale);
|
||||||
|
+ __m128i scale = _mm_sub_epi32(_mm_set1_epi32(256),
|
||||||
|
+ _mm_srli_epi32(src, 24));
|
||||||
|
+ __m128i scale_x2 = _mm_or_si128(_mm_slli_epi32(scale, 16), scale);
|
||||||
|
+
|
||||||
|
+ __m128i rb = _mm_and_si128(_mm_set1_epi32(0x00ff00ff), dst);
|
||||||
|
+ rb = _mm_mullo_epi16(rb, scale_x2);
|
||||||
|
+ rb = _mm_srli_epi16(rb, 8);
|
||||||
|
|
||||||
|
- // uint32_t rb = ((c & mask) * scale) >> 8
|
||||||
|
- __m128i rb = _mm_and_si128(mask, c);
|
||||||
|
- rb = _mm_mullo_epi16(rb, s);
|
||||||
|
- rb = _mm_srli_epi16(rb, 8);
|
||||||
|
+ __m128i ga = _mm_srli_epi16(dst, 8);
|
||||||
|
+ ga = _mm_mullo_epi16(ga, scale_x2);
|
||||||
|
+ ga = _mm_andnot_si128(_mm_set1_epi32(0x00ff00ff), ga);
|
||||||
|
+
|
||||||
|
+ return _mm_add_epi32(src, _mm_or_si128(rb, ga));
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
- // uint32_t ag = ((c >> 8) & mask) * scale
|
||||||
|
- __m128i ag = _mm_srli_epi16(c, 8);
|
||||||
|
- ag = _mm_mullo_epi16(ag, s);
|
||||||
|
-
|
||||||
|
- // (rb & mask) | (ag & ~mask)
|
||||||
|
- ag = _mm_andnot_si128(mask, ag);
|
||||||
|
- return _mm_or_si128(rb, ag);
|
||||||
|
+#if defined(SK_ARM_HAS_NEON)
|
||||||
|
+ #include <arm_neon.h>
|
||||||
|
+ // SkMulDiv255Round() applied to each lane.
|
||||||
|
+ static inline uint8x8_t SkMulDiv255Round_neon8(uint8x8_t x, uint8x8_t y) {
|
||||||
|
+ uint16x8_t prod = vmull_u8(x, y);
|
||||||
|
+ return vraddhn_u16(prod, vrshrq_n_u16(prod, 8));
|
||||||
|
+ }
|
||||||
|
+ static inline uint8x8x4_t SkPMSrcOver_neon8(uint8x8x4_t dst, uint8x8x4_t src) {
|
||||||
|
+ uint8x8_t nalphas = vmvn_u8(src.val[3]); // 256 - alpha
|
||||||
|
+ return {
|
||||||
|
+ vadd_u8(src.val[0], SkMulDiv255Round_neon8(nalphas, dst.val[0])),
|
||||||
|
+ vadd_u8(src.val[1], SkMulDiv255Round_neon8(nalphas, dst.val[1])),
|
||||||
|
+ vadd_u8(src.val[2], SkMulDiv255Round_neon8(nalphas, dst.val[2])),
|
||||||
|
+ vadd_u8(src.val[3], SkMulDiv255Round_neon8(nalphas, dst.val[3])),
|
||||||
|
};
|
||||||
|
- return _mm_add_epi32(src,
|
||||||
|
- SkAlphaMulQ_SSE2(dst, _mm_sub_epi32(_mm_set1_epi32(256),
|
||||||
|
- _mm_srli_epi32(src, 24))));
|
||||||
|
+ }
|
||||||
|
+ // Variant assuming dst and src contain the color components of two consecutive pixels.
|
||||||
|
+ static inline uint8x8_t SkPMSrcOver_neon2(uint8x8_t dst, uint8x8_t src) {
|
||||||
|
+ const uint8x8_t alpha_indices = vcreate_u8(0x0707070703030303);
|
||||||
|
+ uint8x8_t nalphas = vmvn_u8(vtbl1_u8(src, alpha_indices));
|
||||||
|
+ return vadd_u8(src, SkMulDiv255Round_neon8(nalphas, dst));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace SK_OPTS_NS {
|
||||||
|
|
||||||
|
+/*not static*/
|
||||||
|
+inline void blit_row_s32a_opaque(SkPMColor* dst, const SkPMColor* src, int len, U8CPU alpha) {
|
||||||
|
+ SkASSERT(alpha == 0xFF);
|
||||||
|
+ sk_msan_assert_initialized(src, src+len);
|
||||||
|
+
|
||||||
|
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX2
|
||||||
|
+ while (len >= 8) {
|
||||||
|
+ _mm256_storeu_si256((__m256i*)dst,
|
||||||
|
+ SkPMSrcOver_AVX2(_mm256_loadu_si256((const __m256i*)src),
|
||||||
|
+ _mm256_loadu_si256((const __m256i*)dst)));
|
||||||
|
+ src += 8;
|
||||||
|
+ dst += 8;
|
||||||
|
+ len -= 8;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
|
||||||
|
+ while (len >= 4) {
|
||||||
|
+ _mm_storeu_si128((__m128i*)dst, SkPMSrcOver_SSE2(_mm_loadu_si128((const __m128i*)src),
|
||||||
|
+ _mm_loadu_si128((const __m128i*)dst)));
|
||||||
|
+ src += 4;
|
||||||
|
+ dst += 4;
|
||||||
|
+ len -= 4;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(SK_ARM_HAS_NEON)
|
||||||
|
+ while (len >= 8) {
|
||||||
|
+ vst4_u8((uint8_t*)dst, SkPMSrcOver_neon8(vld4_u8((const uint8_t*)dst),
|
||||||
|
+ vld4_u8((const uint8_t*)src)));
|
||||||
|
+ src += 8;
|
||||||
|
+ dst += 8;
|
||||||
|
+ len -= 8;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (len >= 2) {
|
||||||
|
+ vst1_u8((uint8_t*)dst, SkPMSrcOver_neon2(vld1_u8((const uint8_t*)dst),
|
||||||
|
+ vld1_u8((const uint8_t*)src)));
|
||||||
|
+ src += 2;
|
||||||
|
+ dst += 2;
|
||||||
|
+ len -= 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (len != 0) {
|
||||||
|
+ uint8x8_t result = SkPMSrcOver_neon2(vcreate_u8((uint64_t)*dst),
|
||||||
|
+ vcreate_u8((uint64_t)*src));
|
||||||
|
+ vst1_lane_u32(dst, vreinterpret_u32_u8(result), 0);
|
||||||
|
+ }
|
||||||
|
+ return;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ while (len --> 0) {
|
||||||
|
+ *dst = SkPMSrcOver(*src, *dst);
|
||||||
|
+ src++;
|
||||||
|
+ dst++;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Blend constant color over count src pixels, writing into dst.
|
||||||
|
+/*not static*/
|
||||||
|
inline void blit_row_color32(SkPMColor* dst, const SkPMColor* src, int count, SkPMColor color) {
|
||||||
|
constexpr int N = 4; // 8, 16 also reasonable choices
|
||||||
|
using U32 = skvx::Vec< N, uint32_t>;
|
||||||
|
@@ -120,259 +197,6 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if defined(SK_ARM_HAS_NEON)
|
||||||
|
-
|
||||||
|
-// Return a uint8x8_t value, r, computed as r[i] = SkMulDiv255Round(x[i], y[i]), where r[i], x[i],
|
||||||
|
-// y[i] are the i-th lanes of the corresponding NEON vectors.
|
||||||
|
-static inline uint8x8_t SkMulDiv255Round_neon8(uint8x8_t x, uint8x8_t y) {
|
||||||
|
- uint16x8_t prod = vmull_u8(x, y);
|
||||||
|
- return vraddhn_u16(prod, vrshrq_n_u16(prod, 8));
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-// The implementations of SkPMSrcOver below perform alpha blending consistently with
|
||||||
|
-// SkMulDiv255Round. They compute the color components (numbers in the interval [0, 255]) as:
|
||||||
|
-//
|
||||||
|
-// result_i = src_i + rint(g(src_alpha, dst_i))
|
||||||
|
-//
|
||||||
|
-// where g(x, y) = ((255.0 - x) * y) / 255.0 and rint rounds to the nearest integer.
|
||||||
|
-
|
||||||
|
-// In this variant of SkPMSrcOver each NEON register, dst.val[i], src.val[i], contains the value
|
||||||
|
-// of the same color component for 8 consecutive pixels. The result of this function follows the
|
||||||
|
-// same convention.
|
||||||
|
-static inline uint8x8x4_t SkPMSrcOver_neon8(uint8x8x4_t dst, uint8x8x4_t src) {
|
||||||
|
- uint8x8_t nalphas = vmvn_u8(src.val[3]);
|
||||||
|
- uint8x8x4_t result;
|
||||||
|
- result.val[0] = vadd_u8(src.val[0], SkMulDiv255Round_neon8(nalphas, dst.val[0]));
|
||||||
|
- result.val[1] = vadd_u8(src.val[1], SkMulDiv255Round_neon8(nalphas, dst.val[1]));
|
||||||
|
- result.val[2] = vadd_u8(src.val[2], SkMulDiv255Round_neon8(nalphas, dst.val[2]));
|
||||||
|
- result.val[3] = vadd_u8(src.val[3], SkMulDiv255Round_neon8(nalphas, dst.val[3]));
|
||||||
|
- return result;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-// In this variant of SkPMSrcOver dst and src contain the color components of two consecutive
|
||||||
|
-// pixels. The return value follows the same convention.
|
||||||
|
-static inline uint8x8_t SkPMSrcOver_neon2(uint8x8_t dst, uint8x8_t src) {
|
||||||
|
- const uint8x8_t alpha_indices = vcreate_u8(0x0707070703030303);
|
||||||
|
- uint8x8_t nalphas = vmvn_u8(vtbl1_u8(src, alpha_indices));
|
||||||
|
- return vadd_u8(src, SkMulDiv255Round_neon8(nalphas, dst));
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/*not static*/ inline
|
||||||
|
-void blit_row_s32a_opaque(SkPMColor* dst, const SkPMColor* src, int len, U8CPU alpha) {
|
||||||
|
- SkASSERT(alpha == 0xFF);
|
||||||
|
- sk_msan_assert_initialized(src, src+len);
|
||||||
|
-// Require AVX2 because of AVX2 integer calculation intrinsics in SrcOver
|
||||||
|
-#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX2
|
||||||
|
- while (len >= 32) {
|
||||||
|
- // Load 32 source pixels.
|
||||||
|
- auto s0 = _mm256_loadu_si256((const __m256i*)(src) + 0),
|
||||||
|
- s1 = _mm256_loadu_si256((const __m256i*)(src) + 1),
|
||||||
|
- s2 = _mm256_loadu_si256((const __m256i*)(src) + 2),
|
||||||
|
- s3 = _mm256_loadu_si256((const __m256i*)(src) + 3);
|
||||||
|
-
|
||||||
|
- const auto alphaMask = _mm256_set1_epi32(0xFF000000);
|
||||||
|
-
|
||||||
|
- auto ORed = _mm256_or_si256(s3, _mm256_or_si256(s2, _mm256_or_si256(s1, s0)));
|
||||||
|
- if (_mm256_testz_si256(ORed, alphaMask)) {
|
||||||
|
- // All 32 source pixels are transparent. Nothing to do.
|
||||||
|
- src += 32;
|
||||||
|
- dst += 32;
|
||||||
|
- len -= 32;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- auto d0 = (__m256i*)(dst) + 0,
|
||||||
|
- d1 = (__m256i*)(dst) + 1,
|
||||||
|
- d2 = (__m256i*)(dst) + 2,
|
||||||
|
- d3 = (__m256i*)(dst) + 3;
|
||||||
|
-
|
||||||
|
- auto ANDed = _mm256_and_si256(s3, _mm256_and_si256(s2, _mm256_and_si256(s1, s0)));
|
||||||
|
- if (_mm256_testc_si256(ANDed, alphaMask)) {
|
||||||
|
- // All 32 source pixels are opaque. SrcOver becomes Src.
|
||||||
|
- _mm256_storeu_si256(d0, s0);
|
||||||
|
- _mm256_storeu_si256(d1, s1);
|
||||||
|
- _mm256_storeu_si256(d2, s2);
|
||||||
|
- _mm256_storeu_si256(d3, s3);
|
||||||
|
- src += 32;
|
||||||
|
- dst += 32;
|
||||||
|
- len -= 32;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // TODO: This math is wrong.
|
||||||
|
- // Do SrcOver.
|
||||||
|
- _mm256_storeu_si256(d0, SkPMSrcOver_AVX2(s0, _mm256_loadu_si256(d0)));
|
||||||
|
- _mm256_storeu_si256(d1, SkPMSrcOver_AVX2(s1, _mm256_loadu_si256(d1)));
|
||||||
|
- _mm256_storeu_si256(d2, SkPMSrcOver_AVX2(s2, _mm256_loadu_si256(d2)));
|
||||||
|
- _mm256_storeu_si256(d3, SkPMSrcOver_AVX2(s3, _mm256_loadu_si256(d3)));
|
||||||
|
- src += 32;
|
||||||
|
- dst += 32;
|
||||||
|
- len -= 32;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
|
||||||
|
- while (len >= 16) {
|
||||||
|
- // Load 16 source pixels.
|
||||||
|
- auto s0 = _mm_loadu_si128((const __m128i*)(src) + 0),
|
||||||
|
- s1 = _mm_loadu_si128((const __m128i*)(src) + 1),
|
||||||
|
- s2 = _mm_loadu_si128((const __m128i*)(src) + 2),
|
||||||
|
- s3 = _mm_loadu_si128((const __m128i*)(src) + 3);
|
||||||
|
-
|
||||||
|
- const auto alphaMask = _mm_set1_epi32(0xFF000000);
|
||||||
|
-
|
||||||
|
- auto ORed = _mm_or_si128(s3, _mm_or_si128(s2, _mm_or_si128(s1, s0)));
|
||||||
|
- if (_mm_testz_si128(ORed, alphaMask)) {
|
||||||
|
- // All 16 source pixels are transparent. Nothing to do.
|
||||||
|
- src += 16;
|
||||||
|
- dst += 16;
|
||||||
|
- len -= 16;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- auto d0 = (__m128i*)(dst) + 0,
|
||||||
|
- d1 = (__m128i*)(dst) + 1,
|
||||||
|
- d2 = (__m128i*)(dst) + 2,
|
||||||
|
- d3 = (__m128i*)(dst) + 3;
|
||||||
|
-
|
||||||
|
- auto ANDed = _mm_and_si128(s3, _mm_and_si128(s2, _mm_and_si128(s1, s0)));
|
||||||
|
- if (_mm_testc_si128(ANDed, alphaMask)) {
|
||||||
|
- // All 16 source pixels are opaque. SrcOver becomes Src.
|
||||||
|
- _mm_storeu_si128(d0, s0);
|
||||||
|
- _mm_storeu_si128(d1, s1);
|
||||||
|
- _mm_storeu_si128(d2, s2);
|
||||||
|
- _mm_storeu_si128(d3, s3);
|
||||||
|
- src += 16;
|
||||||
|
- dst += 16;
|
||||||
|
- len -= 16;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // TODO: This math is wrong.
|
||||||
|
- // Do SrcOver.
|
||||||
|
- _mm_storeu_si128(d0, SkPMSrcOver_SSE2(s0, _mm_loadu_si128(d0)));
|
||||||
|
- _mm_storeu_si128(d1, SkPMSrcOver_SSE2(s1, _mm_loadu_si128(d1)));
|
||||||
|
- _mm_storeu_si128(d2, SkPMSrcOver_SSE2(s2, _mm_loadu_si128(d2)));
|
||||||
|
- _mm_storeu_si128(d3, SkPMSrcOver_SSE2(s3, _mm_loadu_si128(d3)));
|
||||||
|
- src += 16;
|
||||||
|
- dst += 16;
|
||||||
|
- len -= 16;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
|
||||||
|
- while (len >= 16) {
|
||||||
|
- // Load 16 source pixels.
|
||||||
|
- auto s0 = _mm_loadu_si128((const __m128i*)(src) + 0),
|
||||||
|
- s1 = _mm_loadu_si128((const __m128i*)(src) + 1),
|
||||||
|
- s2 = _mm_loadu_si128((const __m128i*)(src) + 2),
|
||||||
|
- s3 = _mm_loadu_si128((const __m128i*)(src) + 3);
|
||||||
|
-
|
||||||
|
- const auto alphaMask = _mm_set1_epi32(0xFF000000);
|
||||||
|
-
|
||||||
|
- auto ORed = _mm_or_si128(s3, _mm_or_si128(s2, _mm_or_si128(s1, s0)));
|
||||||
|
- if (0xffff == _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_and_si128(ORed, alphaMask),
|
||||||
|
- _mm_setzero_si128()))) {
|
||||||
|
- // All 16 source pixels are transparent. Nothing to do.
|
||||||
|
- src += 16;
|
||||||
|
- dst += 16;
|
||||||
|
- len -= 16;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- auto d0 = (__m128i*)(dst) + 0,
|
||||||
|
- d1 = (__m128i*)(dst) + 1,
|
||||||
|
- d2 = (__m128i*)(dst) + 2,
|
||||||
|
- d3 = (__m128i*)(dst) + 3;
|
||||||
|
-
|
||||||
|
- auto ANDed = _mm_and_si128(s3, _mm_and_si128(s2, _mm_and_si128(s1, s0)));
|
||||||
|
- if (0xffff == _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_and_si128(ANDed, alphaMask),
|
||||||
|
- alphaMask))) {
|
||||||
|
- // All 16 source pixels are opaque. SrcOver becomes Src.
|
||||||
|
- _mm_storeu_si128(d0, s0);
|
||||||
|
- _mm_storeu_si128(d1, s1);
|
||||||
|
- _mm_storeu_si128(d2, s2);
|
||||||
|
- _mm_storeu_si128(d3, s3);
|
||||||
|
- src += 16;
|
||||||
|
- dst += 16;
|
||||||
|
- len -= 16;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // TODO: This math is wrong.
|
||||||
|
- // Do SrcOver.
|
||||||
|
- _mm_storeu_si128(d0, SkPMSrcOver_SSE2(s0, _mm_loadu_si128(d0)));
|
||||||
|
- _mm_storeu_si128(d1, SkPMSrcOver_SSE2(s1, _mm_loadu_si128(d1)));
|
||||||
|
- _mm_storeu_si128(d2, SkPMSrcOver_SSE2(s2, _mm_loadu_si128(d2)));
|
||||||
|
- _mm_storeu_si128(d3, SkPMSrcOver_SSE2(s3, _mm_loadu_si128(d3)));
|
||||||
|
-
|
||||||
|
- src += 16;
|
||||||
|
- dst += 16;
|
||||||
|
- len -= 16;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#elif defined(SK_ARM_HAS_NEON)
|
||||||
|
- // Do 8-pixels at a time. A 16-pixels at a time version of this code was also tested, but it
|
||||||
|
- // underperformed on some of the platforms under test for inputs with frequent transitions of
|
||||||
|
- // alpha (corresponding to changes of the conditions [~]alpha_u64 == 0 below). It may be worth
|
||||||
|
- // revisiting the situation in the future.
|
||||||
|
- while (len >= 8) {
|
||||||
|
- // Load 8 pixels in 4 NEON registers. src_col.val[i] will contain the same color component
|
||||||
|
- // for 8 consecutive pixels (e.g. src_col.val[3] will contain all alpha components of 8
|
||||||
|
- // pixels).
|
||||||
|
- uint8x8x4_t src_col = vld4_u8(reinterpret_cast<const uint8_t*>(src));
|
||||||
|
- src += 8;
|
||||||
|
- len -= 8;
|
||||||
|
-
|
||||||
|
- // We now detect 2 special cases: the first occurs when all alphas are zero (the 8 pixels
|
||||||
|
- // are all transparent), the second when all alphas are fully set (they are all opaque).
|
||||||
|
- uint8x8_t alphas = src_col.val[3];
|
||||||
|
- uint64_t alphas_u64 = vget_lane_u64(vreinterpret_u64_u8(alphas), 0);
|
||||||
|
- if (alphas_u64 == 0) {
|
||||||
|
- // All pixels transparent.
|
||||||
|
- dst += 8;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (~alphas_u64 == 0) {
|
||||||
|
- // All pixels opaque.
|
||||||
|
- vst4_u8(reinterpret_cast<uint8_t*>(dst), src_col);
|
||||||
|
- dst += 8;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- uint8x8x4_t dst_col = vld4_u8(reinterpret_cast<uint8_t*>(dst));
|
||||||
|
- vst4_u8(reinterpret_cast<uint8_t*>(dst), SkPMSrcOver_neon8(dst_col, src_col));
|
||||||
|
- dst += 8;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // Deal with leftover pixels.
|
||||||
|
- for (; len >= 2; len -= 2, src += 2, dst += 2) {
|
||||||
|
- uint8x8_t src2 = vld1_u8(reinterpret_cast<const uint8_t*>(src));
|
||||||
|
- uint8x8_t dst2 = vld1_u8(reinterpret_cast<const uint8_t*>(dst));
|
||||||
|
- vst1_u8(reinterpret_cast<uint8_t*>(dst), SkPMSrcOver_neon2(dst2, src2));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (len != 0) {
|
||||||
|
- uint8x8_t result = SkPMSrcOver_neon2(vcreate_u8(*dst), vcreate_u8(*src));
|
||||||
|
- vst1_lane_u32(dst, vreinterpret_u32_u8(result), 0);
|
||||||
|
- }
|
||||||
|
- return;
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- while (len-- > 0) {
|
||||||
|
- // This 0xFF000000 is not semantically necessary, but for compatibility
|
||||||
|
- // with chromium:611002 we need to keep it until we figure out where
|
||||||
|
- // the non-premultiplied src values (like 0x00FFFFFF) are coming from.
|
||||||
|
- // TODO(mtklein): sort this out and assert *src is premul here.
|
||||||
|
- if (*src & 0xFF000000) {
|
||||||
|
- *dst = (*src >= 0xFF000000) ? *src : SkPMSrcOver(*src, *dst);
|
||||||
|
- }
|
||||||
|
- src++;
|
||||||
|
- dst++;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
} // SK_OPTS_NS
|
||||||
|
|
||||||
|
#endif//SkBlitRow_opts_DEFINED
|
||||||
102
CVE-2020-26951-1.patch
Normal file
102
CVE-2020-26951-1.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Henri Sivonen <hsivonen@hsivonen.fi>
|
||||||
|
# Date 1603457336 0
|
||||||
|
# Fri Oct 23 12:48:56 2020 +0000
|
||||||
|
# Node ID 9143f95d5ab3896f5461fa1666500f6fc1f9e73b
|
||||||
|
# Parent b067b0d3670b37daad95505b87bddca6bb113d11
|
||||||
|
Bug 1667113. r=smaug
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93482
|
||||||
|
|
||||||
|
diff -r b067b0d3670b -r 9143f95d5ab3 browser/base/content/test/static/browser_parsable_css.js
|
||||||
|
--- a/browser/base/content/test/static/browser_parsable_css.js Fri Oct 23 12:48:52 2020 +0000
|
||||||
|
+++ b/browser/base/content/test/static/browser_parsable_css.js Fri Oct 23 12:48:56 2020 +0000
|
||||||
|
@@ -496,9 +496,9 @@
|
||||||
|
checkWhitelist(propNameWhitelist);
|
||||||
|
|
||||||
|
// Clean up to avoid leaks:
|
||||||
|
- iframe.remove();
|
||||||
|
doc.head.innerHTML = "";
|
||||||
|
doc = null;
|
||||||
|
+ iframe.remove();
|
||||||
|
iframe = null;
|
||||||
|
win = null;
|
||||||
|
hiddenFrame.destroy();
|
||||||
|
diff -r b067b0d3670b -r 9143f95d5ab3 dom/base/nsContentUtils.cpp
|
||||||
|
--- a/dom/base/nsContentUtils.cpp Fri Oct 23 12:48:52 2020 +0000
|
||||||
|
+++ b/dom/base/nsContentUtils.cpp Fri Oct 23 12:48:56 2020 +0000
|
||||||
|
@@ -4817,6 +4817,7 @@
|
||||||
|
|
||||||
|
nsIContent* target = aTargetNode;
|
||||||
|
|
||||||
|
+ RefPtr<Document> inert;
|
||||||
|
RefPtr<DocumentFragment> fragment;
|
||||||
|
// We sanitize if the fragment occurs in a system privileged
|
||||||
|
// context, an about: page, or if there are explicit sanitization flags.
|
||||||
|
@@ -4828,8 +4828,12 @@
|
||||||
|
nodePrincipal->SchemeIs("about") || aFlags >= 0;
|
||||||
|
if (shouldSanitize) {
|
||||||
|
if (!AllowsUnsanitizedContentForAboutNewTab(nodePrincipal)) {
|
||||||
|
- fragment = new (aTargetNode->OwnerDoc()->NodeInfoManager())
|
||||||
|
- DocumentFragment(aTargetNode->OwnerDoc()->NodeInfoManager());
|
||||||
|
+ inert = nsContentUtils::CreateInertHTMLDocument(aTargetNode->OwnerDoc());
|
||||||
|
+ if (!inert) {
|
||||||
|
+ return NS_ERROR_FAILURE;
|
||||||
|
+ }
|
||||||
|
+ fragment = new (inert->NodeInfoManager())
|
||||||
|
+ DocumentFragment(inert->NodeInfoManager());
|
||||||
|
target = fragment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -4908,22 +4908,7 @@
|
||||||
|
MOZ_ASSERT(contentsink, "Sink doesn't QI to nsIContentSink!");
|
||||||
|
sXMLFragmentParser->SetContentSink(contentsink);
|
||||||
|
|
||||||
|
- sXMLFragmentSink->SetTargetDocument(aDocument);
|
||||||
|
- sXMLFragmentSink->SetPreventScriptExecution(aPreventScriptExecution);
|
||||||
|
-
|
||||||
|
- nsresult rv = sXMLFragmentParser->ParseFragment(aSourceBuffer, aTagStack);
|
||||||
|
- if (NS_FAILED(rv)) {
|
||||||
|
- // Drop the fragment parser and sink that might be in an inconsistent state
|
||||||
|
- NS_IF_RELEASE(sXMLFragmentParser);
|
||||||
|
- NS_IF_RELEASE(sXMLFragmentSink);
|
||||||
|
- return rv;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- rv = sXMLFragmentSink->FinishFragmentParsing(aReturn);
|
||||||
|
-
|
||||||
|
- sXMLFragmentParser->Reset();
|
||||||
|
- NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
-
|
||||||
|
+ RefPtr<Document> doc;
|
||||||
|
nsCOMPtr<nsIPrincipal> nodePrincipal = aDocument->NodePrincipal();
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
@@ -4929,6 +4929,27 @@
|
||||||
|
// an about: scheme principal.
|
||||||
|
bool shouldSanitize = nodePrincipal->IsSystemPrincipal() ||
|
||||||
|
nodePrincipal->SchemeIs("about") || aFlags >= 0;
|
||||||
|
+ if (shouldSanitize) {
|
||||||
|
+ doc = nsContentUtils::CreateInertXMLDocument(aDocument);
|
||||||
|
+ } else {
|
||||||
|
+ doc = aDocument;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sXMLFragmentSink->SetTargetDocument(doc);
|
||||||
|
+ sXMLFragmentSink->SetPreventScriptExecution(aPreventScriptExecution);
|
||||||
|
+
|
||||||
|
+ nsresult rv = sXMLFragmentParser->ParseFragment(aSourceBuffer, aTagStack);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ // Drop the fragment parser and sink that might be in an inconsistent state
|
||||||
|
+ NS_IF_RELEASE(sXMLFragmentParser);
|
||||||
|
+ NS_IF_RELEASE(sXMLFragmentSink);
|
||||||
|
+ return rv;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = sXMLFragmentSink->FinishFragmentParsing(aReturn);
|
||||||
|
+
|
||||||
|
+ sXMLFragmentParser->Reset();
|
||||||
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (shouldSanitize) {
|
||||||
|
uint32_t sanitizationFlags =
|
||||||
177
CVE-2020-26951-2.patch
Normal file
177
CVE-2020-26951-2.patch
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Henri Sivonen <hsivonen@hsivonen.fi>
|
||||||
|
# Date 1605719930 0
|
||||||
|
# Wed Nov 18 17:18:50 2020 +0000
|
||||||
|
# Node ID 027514ba89006dfd5c346c307e46ed8f79e358c1
|
||||||
|
# Parent 782446e715644da3ca8226d0c3413e3fafb69d6f
|
||||||
|
Bug 1667113 test - Test innerHTML sanitizer in chrome context. r=smaug
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93928
|
||||||
|
|
||||||
|
diff -r 782446e71564 -r 027514ba8900 dom/security/test/general/chrome.ini
|
||||||
|
--- a/dom/security/test/general/chrome.ini Wed Nov 18 17:18:56 2020 +0000
|
||||||
|
+++ b/dom/security/test/general/chrome.ini Wed Nov 18 17:18:50 2020 +0000
|
||||||
|
@@ -3,6 +3,8 @@
|
||||||
|
favicon_bug1277803.ico
|
||||||
|
bug1277803.html
|
||||||
|
|
||||||
|
+[test_innerhtml_sanitizer.html]
|
||||||
|
+[test_innerhtml_sanitizer.xhtml]
|
||||||
|
[test_bug1277803.xhtml]
|
||||||
|
skip-if = os == 'android' || verify
|
||||||
|
|
||||||
|
diff -r 782446e71564 -r 027514ba8900 dom/security/test/general/test_innerhtml_sanitizer.html
|
||||||
|
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||||
|
+++ b/dom/security/test/general/test_innerhtml_sanitizer.html Wed Nov 18 17:18:50 2020 +0000
|
||||||
|
@@ -0,0 +1,74 @@
|
||||||
|
+<!DOCTYPE HTML>
|
||||||
|
+<html>
|
||||||
|
+<head>
|
||||||
|
+ <meta charset=utf-8>
|
||||||
|
+ <title>Test for Bug 1667113</title>
|
||||||
|
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||||
|
+</head>
|
||||||
|
+<body>
|
||||||
|
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1667113">Mozilla Bug 1667113</a>
|
||||||
|
+<div></div>
|
||||||
|
+<script>
|
||||||
|
+SimpleTest.waitForExplicitFinish();
|
||||||
|
+
|
||||||
|
+// Please note that 'fakeServer' does not exist because the test relies
|
||||||
|
+// on "csp-on-violate-policy" , and "specialpowers-http-notify-request"
|
||||||
|
+// which fire if either the request is blocked or fires. The test does
|
||||||
|
+// not rely on the result of the load.
|
||||||
|
+
|
||||||
|
+function fail() {
|
||||||
|
+ ok(false, "Should not call this")
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function examiner() {
|
||||||
|
+ SpecialPowers.addObserver(this, "csp-on-violate-policy");
|
||||||
|
+ SpecialPowers.addObserver(this, "specialpowers-http-notify-request");
|
||||||
|
+}
|
||||||
|
+examiner.prototype = {
|
||||||
|
+ observe(subject, topic, data) {
|
||||||
|
+ if (topic === "csp-on-violate-policy") {
|
||||||
|
+ let asciiSpec = SpecialPowers.getPrivilegedProps(
|
||||||
|
+ SpecialPowers.do_QueryInterface(subject, "nsIURI"),
|
||||||
|
+ "asciiSpec");
|
||||||
|
+ if (asciiSpec.includes("fakeServer")) {
|
||||||
|
+ ok (false, "Should not attempt fetch, not even blocked by CSP.");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (topic === "specialpowers-http-notify-request") {
|
||||||
|
+ if (data.includes("fakeServer")) {
|
||||||
|
+ ok (false, "Should not try fetch");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ remove() {
|
||||||
|
+ SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||||
|
+ SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+window.examiner = new examiner();
|
||||||
|
+
|
||||||
|
+let div = document.getElementsByTagName("div")[0];
|
||||||
|
+div.innerHTML = "<svg><style><title><audio src=fakeServer onerror=fail() onload=fail()>";
|
||||||
|
+
|
||||||
|
+let svg = div.firstChild;
|
||||||
|
+is(svg.nodeName, "svg", "Node name should be svg");
|
||||||
|
+
|
||||||
|
+let style = svg.firstChild;
|
||||||
|
+if (style) {
|
||||||
|
+ is(style.firstChild, null, "Style should not have child nodes.");
|
||||||
|
+} else {
|
||||||
|
+ ok(false, "Should have gotten a node.");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+SimpleTest.executeSoon(function() {
|
||||||
|
+ window.examiner.remove();
|
||||||
|
+ SimpleTest.finish();
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+</script>
|
||||||
|
+</body>
|
||||||
|
+</html>
|
||||||
|
diff -r 782446e71564 -r 027514ba8900 dom/security/test/general/test_innerhtml_sanitizer.xhtml
|
||||||
|
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||||
|
+++ b/dom/security/test/general/test_innerhtml_sanitizer.xhtml Wed Nov 18 17:18:50 2020 +0000
|
||||||
|
@@ -0,0 +1,73 @@
|
||||||
|
+<!DOCTYPE HTML>
|
||||||
|
+<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
+<head>
|
||||||
|
+ <title>Test for Bug 1667113</title>
|
||||||
|
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||||
|
+</head>
|
||||||
|
+<body>
|
||||||
|
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1667113">Mozilla Bug 1667113</a>
|
||||||
|
+<div></div>
|
||||||
|
+<script><![CDATA[
|
||||||
|
+SimpleTest.waitForExplicitFinish();
|
||||||
|
+
|
||||||
|
+// Please note that 'fakeServer' does not exist because the test relies
|
||||||
|
+// on "csp-on-violate-policy" , and "specialpowers-http-notify-request"
|
||||||
|
+// which fire if either the request is blocked or fires. The test does
|
||||||
|
+// not rely on the result of the load.
|
||||||
|
+
|
||||||
|
+function fail() {
|
||||||
|
+ ok(false, "Should not call this")
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function examiner() {
|
||||||
|
+ SpecialPowers.addObserver(this, "csp-on-violate-policy");
|
||||||
|
+ SpecialPowers.addObserver(this, "specialpowers-http-notify-request");
|
||||||
|
+}
|
||||||
|
+examiner.prototype = {
|
||||||
|
+ observe(subject, topic, data) {
|
||||||
|
+ if (topic === "csp-on-violate-policy") {
|
||||||
|
+ let asciiSpec = SpecialPowers.getPrivilegedProps(
|
||||||
|
+ SpecialPowers.do_QueryInterface(subject, "nsIURI"),
|
||||||
|
+ "asciiSpec");
|
||||||
|
+ if (asciiSpec.includes("fakeServer")) {
|
||||||
|
+ ok (false, "Should not attempt fetch, not even blocked by CSP.");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (topic === "specialpowers-http-notify-request") {
|
||||||
|
+ if (data.includes("fakeServer")) {
|
||||||
|
+ ok (false, "Should not try fetch");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ remove() {
|
||||||
|
+ SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||||
|
+ SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+window.examiner = new examiner();
|
||||||
|
+
|
||||||
|
+let div = document.getElementsByTagName("div")[0];
|
||||||
|
+div.innerHTML = "<svg xmlns='http://www.w3.org/2000/svg'><style><title><audio xmlns='http://www.w3.org/1999/xhtml' src='fakeServer' onerror='fail()' onload='fail()'></audio></title></style></svg>";
|
||||||
|
+
|
||||||
|
+let svg = div.firstChild;
|
||||||
|
+is(svg.nodeName, "svg", "Node name should be svg");
|
||||||
|
+
|
||||||
|
+let style = svg.firstChild;
|
||||||
|
+if (style) {
|
||||||
|
+ is(style.firstChild, null, "Style should not have child nodes.");
|
||||||
|
+} else {
|
||||||
|
+ ok(false, "Should have gotten a node.");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+SimpleTest.executeSoon(function() {
|
||||||
|
+ window.examiner.remove();
|
||||||
|
+ SimpleTest.finish();
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+]]></script>
|
||||||
|
+</body>
|
||||||
|
+</html>
|
||||||
85
CVE-2020-26953-pre.patch
Normal file
85
CVE-2020-26953-pre.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Alphan Chen <alchen@mozilla.com>
|
||||||
|
# Date 1593745253 0
|
||||||
|
# Fri Jul 03 03:00:53 2020 +0000
|
||||||
|
# Node ID aff172a1f77244bf24cfccc966c917bf801b5cbd
|
||||||
|
# Parent d69131a21feedc02c202912955ae015c74c4c8ec
|
||||||
|
Bug 1644484 - Handle the TypeError and InvalidStateError when calling FullScreen.cleanupDomFullscreen() from DOMFullscreenParent.didDestroy() r=Gijs
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D81716
|
||||||
|
|
||||||
|
diff -r d69131a21fee -r aff172a1f772 browser/base/content/browser-fullScreenAndPointerLock.js
|
||||||
|
--- a/browser/base/content/browser-fullScreenAndPointerLock.js Fri Jul 03 01:30:12 2020 +0000
|
||||||
|
+++ b/browser/base/content/browser-fullScreenAndPointerLock.js Fri Jul 03 03:00:53 2020 +0000
|
||||||
|
@@ -345,7 +345,9 @@
|
||||||
|
},
|
||||||
|
|
||||||
|
exitDomFullScreen() {
|
||||||
|
- document.exitFullscreen();
|
||||||
|
+ if (document.fullscreen) {
|
||||||
|
+ document.exitFullscreen();
|
||||||
|
+ }
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEvent(event) {
|
||||||
|
@@ -508,8 +510,15 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for the first ancestor of aActor that lives in a different process.
|
||||||
|
- * If found, that ancestor is sent the message. Otherwise, the recipient should
|
||||||
|
- * be the actor of the request origin.
|
||||||
|
+ * If found, that ancestor is sent the message and return false.
|
||||||
|
+ * Otherwise, the recipient should be the actor of the request origin and return true
|
||||||
|
+ * from this function.
|
||||||
|
+ *
|
||||||
|
+ * The method will be called again as a result of targeted child process doing
|
||||||
|
+ * "FullScreen.enterDomFullscreen()" or "FullScreen.cleanupDomFullscreen()".
|
||||||
|
+ * The return value is used to postpone entering or exiting Full Screen in the parent
|
||||||
|
+ * until there is no ancestor anymore.
|
||||||
|
+ *
|
||||||
|
*
|
||||||
|
* @param {JSWindowActorParent} aActor
|
||||||
|
* The actor that called this function.
|
||||||
|
@@ -517,6 +526,10 @@
|
||||||
|
* Message to be sent.
|
||||||
|
*
|
||||||
|
* @return {boolean}
|
||||||
|
+ * The return value is used to postpone entering or exiting Full Screen in the
|
||||||
|
+ * parent until there is no ancestor anymore.
|
||||||
|
+ * Return false if the message is send to the first ancestor of aActor that
|
||||||
|
+ * lives in a different process
|
||||||
|
* Return true if the message is sent to the request source
|
||||||
|
* or false otherwise.
|
||||||
|
*/
|
||||||
|
@@ -530,6 +543,9 @@
|
||||||
|
let parentBC = childBC.parent;
|
||||||
|
|
||||||
|
while (parentBC) {
|
||||||
|
+ if (!childBC.currentWindowGlobal || !parentBC.currentWindowGlobal) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
let childPid = childBC.currentWindowGlobal.osPid;
|
||||||
|
let parentPid = parentBC.currentWindowGlobal.osPid;
|
||||||
|
|
||||||
|
@@ -541,7 +557,7 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (parentBC) {
|
||||||
|
+ if (parentBC && parentBC.currentWindowGlobal) {
|
||||||
|
let parentActor = parentBC.currentWindowGlobal.getActor("DOMFullscreen");
|
||||||
|
parentActor.sendAsyncMessage(aMessage, {
|
||||||
|
remoteFrameBC: childBC,
|
||||||
|
@@ -554,8 +570,10 @@
|
||||||
|
// have entered or exited fullscreen at this point.
|
||||||
|
// So let's notify the process where the original request
|
||||||
|
// comes from.
|
||||||
|
- aActor.requestOrigin.sendAsyncMessage(aMessage, {});
|
||||||
|
- aActor.requestOrigin = null;
|
||||||
|
+ if (!aActor.requestOrigin.hasBeenDestroyed()) {
|
||||||
|
+ aActor.requestOrigin.sendAsyncMessage(aMessage, {});
|
||||||
|
+ aActor.requestOrigin = null;
|
||||||
|
+ }
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
231
CVE-2020-26953.patch
Normal file
231
CVE-2020-26953.patch
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Steven MacLeod <steven@smacleod.ca>
|
||||||
|
# Date 1601937483 0
|
||||||
|
# Mon Oct 05 22:38:03 2020 +0000
|
||||||
|
# Node ID 3e884c48633fb4017402ef2c7053f8d947676dd5
|
||||||
|
# Parent b4b7e943b93cdc77a479bd5484f7661985bdb7d4
|
||||||
|
Bug 1656741, r=Gijs
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D91760
|
||||||
|
|
||||||
|
diff -r b4b7e943b93c -r 3e884c48633f browser/actors/DOMFullscreenParent.jsm
|
||||||
|
--- a/browser/actors/DOMFullscreenParent.jsm Mon Oct 05 22:20:41 2020 +0000
|
||||||
|
+++ b/browser/actors/DOMFullscreenParent.jsm Mon Oct 05 22:38:03 2020 +0000
|
||||||
|
@@ -9,6 +9,8 @@
|
||||||
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
class DOMFullscreenParent extends JSWindowActorParent {
|
||||||
|
+ waitingForChildFullscreen = false;
|
||||||
|
+
|
||||||
|
updateFullscreenWindowReference(aWindow) {
|
||||||
|
if (aWindow.document.documentElement.hasAttribute("inDOMFullscreen")) {
|
||||||
|
this._fullscreenWindow = aWindow;
|
||||||
|
@@ -23,6 +25,20 @@
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (this.waitingForChildFullscreen) {
|
||||||
|
+ // We were killed while waiting for our DOMFullscreenChild
|
||||||
|
+ // to transition to fullscreen so we abort the entire
|
||||||
|
+ // fullscreen transition to prevent getting stuck in a
|
||||||
|
+ // partial fullscreen state. We need to go through the
|
||||||
|
+ // document since window.Fullscreen could be undefined
|
||||||
|
+ // at this point.
|
||||||
|
+ //
|
||||||
|
+ // This could reject if we're not currently in fullscreen
|
||||||
|
+ // so just ignore rejection.
|
||||||
|
+ window.document.exitFullscreen().catch(() => {});
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Need to resume Chrome UI if the window is still in fullscreen UI
|
||||||
|
// to avoid the window stays in fullscreen problem. (See Bug 1620341)
|
||||||
|
if (window.document.documentElement.hasAttribute("inDOMFullscreen")) {
|
||||||
|
@@ -64,6 +80,7 @@
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "DOMFullscreen:Entered": {
|
||||||
|
+ this.waitingForChildFullscreen = false;
|
||||||
|
window.FullScreen.enterDomFullscreen(browser, this);
|
||||||
|
this.updateFullscreenWindowReference(window);
|
||||||
|
break;
|
||||||
|
diff -r b4b7e943b93c -r 3e884c48633f browser/base/content/browser-fullScreenAndPointerLock.js
|
||||||
|
--- a/browser/base/content/browser-fullScreenAndPointerLock.js Mon Oct 05 22:20:41 2020 +0000
|
||||||
|
+++ b/browser/base/content/browser-fullScreenAndPointerLock.js Mon Oct 05 22:38:03 2020 +0000
|
||||||
|
@@ -420,12 +420,27 @@
|
||||||
|
// before the check is fine since we also check the activeness of
|
||||||
|
// the requesting document in content-side handling code.
|
||||||
|
if (this._isRemoteBrowser(aBrowser)) {
|
||||||
|
- if (
|
||||||
|
- !this._sendMessageToTheRightContent(aActor, "DOMFullscreen:Entered")
|
||||||
|
- ) {
|
||||||
|
+ let [targetActor, inProcessBC] = this._getNextMsgRecipientActor(aActor);
|
||||||
|
+ if (!targetActor) {
|
||||||
|
+ // If there is no appropriate actor to send the message we have
|
||||||
|
+ // no way to complete the transition and should abort by exiting
|
||||||
|
+ // fullscreen.
|
||||||
|
+ this._abortEnterFullscreen();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ targetActor.sendAsyncMessage("DOMFullscreen:Entered", {
|
||||||
|
+ remoteFrameBC: inProcessBC,
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ // Record that the actor is waiting for its child to enter
|
||||||
|
+ // fullscreen so that if it dies we can abort.
|
||||||
|
+ targetActor.waitingForChildFullscreen = true;
|
||||||
|
+ if (inProcessBC) {
|
||||||
|
+ // We aren't messaging the request origin yet, skip this time.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
// If we've received a fullscreen notification, we have to ensure that the
|
||||||
|
// element that's requesting fullscreen belongs to the browser that's currently
|
||||||
|
// active. If not, we exit fullscreen since the "full-screen document" isn't
|
||||||
|
@@ -437,9 +452,7 @@
|
||||||
|
// full-screen was made. Cancel full-screen.
|
||||||
|
Services.focus.activeWindow != window
|
||||||
|
) {
|
||||||
|
- // This function is called synchronously in fullscreen change, so
|
||||||
|
- // we have to avoid calling exitFullscreen synchronously here.
|
||||||
|
- setTimeout(() => document.exitFullscreen(), 0);
|
||||||
|
+ this._abortEnterFullscreen();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -453,7 +466,6 @@
|
||||||
|
this._logWarningPermissionPromptFS("promptCanceled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
document.documentElement.setAttribute("inDOMFullscreen", true);
|
||||||
|
|
||||||
|
if (gFindBarInitialized) {
|
||||||
|
@@ -488,9 +500,25 @@
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
+ /**
|
||||||
|
+ * Clean up full screen, starting from the request origin's first ancestor
|
||||||
|
+ * frame that is OOP.
|
||||||
|
+ *
|
||||||
|
+ * If there are OOP ancestor frames, we notify the first of those and then bail to
|
||||||
|
+ * be called again in that process when it has dealt with the change. This is
|
||||||
|
+ * repeated until all ancestor processes have been updated. Once that has happened
|
||||||
|
+ * we remove our handlers and attributes and notify the request origin to complete
|
||||||
|
+ * the cleanup.
|
||||||
|
+ */
|
||||||
|
cleanupDomFullscreen(aActor) {
|
||||||
|
- if (!this._sendMessageToTheRightContent(aActor, "DOMFullscreen:CleanUp")) {
|
||||||
|
- return;
|
||||||
|
+ let [target, inProcessBC] = this._getNextMsgRecipientActor(aActor);
|
||||||
|
+ if (target) {
|
||||||
|
+ target.sendAsyncMessage("DOMFullscreen:CleanUp", {
|
||||||
|
+ remoteFrameBC: inProcessBC,
|
||||||
|
+ });
|
||||||
|
+ if (inProcessBC) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupNotifications.panel.removeEventListener(
|
||||||
|
@@ -508,40 +536,43 @@
|
||||||
|
document.documentElement.removeAttribute("inDOMFullscreen");
|
||||||
|
},
|
||||||
|
|
||||||
|
+ _abortEnterFullscreen() {
|
||||||
|
+ // This function is called synchronously in fullscreen change, so
|
||||||
|
+ // we have to avoid calling exitFullscreen synchronously here.
|
||||||
|
+ setTimeout(() => document.exitFullscreen(), 0);
|
||||||
|
+ if (TelemetryStopwatch.running("FULLSCREEN_CHANGE_MS")) {
|
||||||
|
+ // Cancel the stopwatch for any fullscreen change to avoid
|
||||||
|
+ // errors if it is started again.
|
||||||
|
+ TelemetryStopwatch.cancel("FULLSCREEN_CHANGE_MS");
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Search for the first ancestor of aActor that lives in a different process.
|
||||||
|
- * If found, that ancestor is sent the message and return false.
|
||||||
|
- * Otherwise, the recipient should be the actor of the request origin and return true
|
||||||
|
- * from this function.
|
||||||
|
- *
|
||||||
|
- * The method will be called again as a result of targeted child process doing
|
||||||
|
- * "FullScreen.enterDomFullscreen()" or "FullScreen.cleanupDomFullscreen()".
|
||||||
|
- * The return value is used to postpone entering or exiting Full Screen in the parent
|
||||||
|
- * until there is no ancestor anymore.
|
||||||
|
+ * If found, that ancestor actor and the browsing context for its child which
|
||||||
|
+ * was in process are returned. Otherwise [request origin, null].
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {JSWindowActorParent} aActor
|
||||||
|
* The actor that called this function.
|
||||||
|
- * @param {String} message
|
||||||
|
- * Message to be sent.
|
||||||
|
*
|
||||||
|
- * @return {boolean}
|
||||||
|
- * The return value is used to postpone entering or exiting Full Screen in the
|
||||||
|
- * parent until there is no ancestor anymore.
|
||||||
|
- * Return false if the message is send to the first ancestor of aActor that
|
||||||
|
- * lives in a different process
|
||||||
|
- * Return true if the message is sent to the request source
|
||||||
|
- * or false otherwise.
|
||||||
|
+ * @return {[JSWindowActorParent, BrowsingContext]}
|
||||||
|
+ * The parent actor which should be sent the next msg and the
|
||||||
|
+ * in process browsing context which is its child. Will be
|
||||||
|
+ * [null, null] if there is no OOP parent actor and request origin
|
||||||
|
+ * is unset. [null, null] is also returned if the intended actor or
|
||||||
|
+ * the calling actor has been destroyed.
|
||||||
|
*/
|
||||||
|
- _sendMessageToTheRightContent(aActor, aMessage) {
|
||||||
|
+ _getNextMsgRecipientActor(aActor) {
|
||||||
|
if (aActor.hasBeenDestroyed()) {
|
||||||
|
- // Just restore the chrome UI when the actor is dead.
|
||||||
|
- return true;
|
||||||
|
+ return [null, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
let childBC = aActor.browsingContext;
|
||||||
|
let parentBC = childBC.parent;
|
||||||
|
|
||||||
|
+ // Walk up the browsing context tree from aActor's browsing context
|
||||||
|
+ // to find the first ancestor browsing context that's in a different process.
|
||||||
|
while (parentBC) {
|
||||||
|
if (!childBC.currentWindowGlobal || !parentBC.currentWindowGlobal) {
|
||||||
|
break;
|
||||||
|
@@ -557,24 +588,20 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ let target = null;
|
||||||
|
+ let inProcessBC = null;
|
||||||
|
+
|
||||||
|
if (parentBC && parentBC.currentWindowGlobal) {
|
||||||
|
- let parentActor = parentBC.currentWindowGlobal.getActor("DOMFullscreen");
|
||||||
|
- parentActor.sendAsyncMessage(aMessage, {
|
||||||
|
- remoteFrameBC: childBC,
|
||||||
|
- });
|
||||||
|
- return false;
|
||||||
|
+ target = parentBC.currentWindowGlobal.getActor("DOMFullscreen");
|
||||||
|
+ inProcessBC = childBC;
|
||||||
|
+ } else {
|
||||||
|
+ target = aActor.requestOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
- // All content frames living outside the process where
|
||||||
|
- // the element requesting fullscreen lives should
|
||||||
|
- // have entered or exited fullscreen at this point.
|
||||||
|
- // So let's notify the process where the original request
|
||||||
|
- // comes from.
|
||||||
|
- if (!aActor.requestOrigin.hasBeenDestroyed()) {
|
||||||
|
- aActor.requestOrigin.sendAsyncMessage(aMessage, {});
|
||||||
|
- aActor.requestOrigin = null;
|
||||||
|
+ if (!target || target.hasBeenDestroyed()) {
|
||||||
|
+ return [null, null];
|
||||||
|
}
|
||||||
|
- return true;
|
||||||
|
+ return [target, inProcessBC];
|
||||||
|
},
|
||||||
|
|
||||||
|
_isRemoteBrowser(aBrowser) {
|
||||||
56
CVE-2020-26956-1.patch
Normal file
56
CVE-2020-26956-1.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Henri Sivonen <hsivonen@hsivonen.fi>
|
||||||
|
# Date 1603457329 0
|
||||||
|
# Fri Oct 23 12:48:49 2020 +0000
|
||||||
|
# Node ID 3476387362fb15c82f133f390afef719ad36de0a
|
||||||
|
# Parent fd45fcfd6261e9ed6cf83e54ad8286717f1b4762
|
||||||
|
Bug 1666300 part 1 - Remove attributes from descendants when setting sanitized style. r=smaug
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93215
|
||||||
|
|
||||||
|
diff -r fd45fcfd6261 -r 3476387362fb dom/base/nsTreeSanitizer.cpp
|
||||||
|
--- a/dom/base/nsTreeSanitizer.cpp Fri Oct 23 13:04:19 2020 +0000
|
||||||
|
+++ b/dom/base/nsTreeSanitizer.cpp Fri Oct 23 12:48:49 2020 +0000
|
||||||
|
@@ -1341,6 +1341,7 @@
|
||||||
|
nsAutoString sanitizedStyle;
|
||||||
|
SanitizeStyleSheet(styleText, sanitizedStyle, aRoot->OwnerDoc(),
|
||||||
|
node->GetBaseURI());
|
||||||
|
+ RemoveAllAttributesFromDescendants(elt);
|
||||||
|
nsContentUtils::SetNodeTextContent(node, sanitizedStyle, true);
|
||||||
|
|
||||||
|
if (!mOnlyConditionalCSS) {
|
||||||
|
@@ -1427,6 +1428,18 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void nsTreeSanitizer::RemoveAllAttributesFromDescendants(
|
||||||
|
+ mozilla::dom::Element* aElement) {
|
||||||
|
+ nsIContent* node = aElement->GetFirstChild();
|
||||||
|
+ while (node) {
|
||||||
|
+ if (node->IsElement()) {
|
||||||
|
+ mozilla::dom::Element* elt = node->AsElement();
|
||||||
|
+ RemoveAllAttributes(elt);
|
||||||
|
+ }
|
||||||
|
+ node = node->GetNextNode(aElement);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void nsTreeSanitizer::LogMessage(const char* aMessage, Document* aDoc,
|
||||||
|
Element* aElement, nsAtom* aAttr) {
|
||||||
|
if (mLogRemovals) {
|
||||||
|
diff -r fd45fcfd6261 -r 3476387362fb dom/base/nsTreeSanitizer.h
|
||||||
|
--- a/dom/base/nsTreeSanitizer.h Fri Oct 23 13:04:19 2020 +0000
|
||||||
|
+++ b/dom/base/nsTreeSanitizer.h Fri Oct 23 12:48:49 2020 +0000
|
||||||
|
@@ -200,6 +200,12 @@
|
||||||
|
void RemoveAllAttributes(mozilla::dom::Element* aElement);
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * Removes all attributes from the descendants of an element but not from
|
||||||
|
+ * the element itself.
|
||||||
|
+ */
|
||||||
|
+ void RemoveAllAttributesFromDescendants(mozilla::dom::Element* aElement);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
* Log a Console Service message to indicate we removed something.
|
||||||
|
* If you pass an element and/or attribute, their information will
|
||||||
|
* be appended to the message.
|
||||||
171
CVE-2020-26956-2.patch
Normal file
171
CVE-2020-26956-2.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Henri Sivonen <hsivonen@hsivonen.fi>
|
||||||
|
# Date 1603457332 0
|
||||||
|
# Fri Oct 23 12:48:52 2020 +0000
|
||||||
|
# Node ID b067b0d3670b37daad95505b87bddca6bb113d11
|
||||||
|
# Parent 3476387362fb15c82f133f390afef719ad36de0a
|
||||||
|
Bug 1666300 part 2 - Parse into an inert document. r=smaug
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93478
|
||||||
|
|
||||||
|
diff -r 3476387362fb -r b067b0d3670b dom/base/nsContentUtils.cpp
|
||||||
|
--- a/dom/base/nsContentUtils.cpp Fri Oct 23 12:48:49 2020 +0000
|
||||||
|
+++ b/dom/base/nsContentUtils.cpp Fri Oct 23 12:48:52 2020 +0000
|
||||||
|
@@ -4968,17 +4968,12 @@
|
||||||
|
nsAString& aResultBuffer,
|
||||||
|
uint32_t aFlags,
|
||||||
|
uint32_t aWrapCol) {
|
||||||
|
- nsCOMPtr<nsIURI> uri;
|
||||||
|
- NS_NewURI(getter_AddRefs(uri), "about:blank");
|
||||||
|
- nsCOMPtr<nsIPrincipal> principal =
|
||||||
|
- NullPrincipal::CreateWithoutOriginAttributes();
|
||||||
|
- RefPtr<Document> document;
|
||||||
|
- nsresult rv = NS_NewDOMDocument(getter_AddRefs(document), EmptyString(),
|
||||||
|
- EmptyString(), nullptr, uri, uri, principal,
|
||||||
|
- true, nullptr, DocumentFlavorHTML);
|
||||||
|
- NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
-
|
||||||
|
- rv = nsContentUtils::ParseDocumentHTML(
|
||||||
|
+ RefPtr<Document> document = nsContentUtils::CreateInertHTMLDocument(nullptr);
|
||||||
|
+ if (!document) {
|
||||||
|
+ return NS_ERROR_FAILURE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nsresult rv = nsContentUtils::ParseDocumentHTML(
|
||||||
|
aSourceBuffer, document,
|
||||||
|
!(aFlags & nsIDocumentEncoder::OutputNoScriptContent));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@@ -4994,6 +4989,58 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
+already_AddRefed<Document> nsContentUtils::CreateInertXMLDocument(
|
||||||
|
+ const Document* aTemplate) {
|
||||||
|
+ return nsContentUtils::CreateInertDocument(aTemplate, DocumentFlavorXML);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* static */
|
||||||
|
+already_AddRefed<Document> nsContentUtils::CreateInertHTMLDocument(
|
||||||
|
+ const Document* aTemplate) {
|
||||||
|
+ return nsContentUtils::CreateInertDocument(aTemplate, DocumentFlavorHTML);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* static */
|
||||||
|
+already_AddRefed<Document> nsContentUtils::CreateInertDocument(
|
||||||
|
+ const Document* aTemplate, DocumentFlavor aFlavor) {
|
||||||
|
+ if (aTemplate) {
|
||||||
|
+ bool hasHad = true;
|
||||||
|
+ nsIScriptGlobalObject* sgo = aTemplate->GetScriptHandlingObject(hasHad);
|
||||||
|
+ NS_ENSURE_TRUE(sgo || !hasHad, nullptr);
|
||||||
|
+
|
||||||
|
+ nsCOMPtr<Document> doc;
|
||||||
|
+ nsresult rv = NS_NewDOMDocument(
|
||||||
|
+ getter_AddRefs(doc), NS_LITERAL_STRING(""), NS_LITERAL_STRING(""), nullptr,
|
||||||
|
+ aTemplate->GetDocumentURI(), aTemplate->GetDocBaseURI(),
|
||||||
|
+ aTemplate->NodePrincipal(), true, sgo, aFlavor);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ return doc.forget();
|
||||||
|
+ }
|
||||||
|
+ nsCOMPtr<nsIURI> uri;
|
||||||
|
+ NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:blank"));
|
||||||
|
+ if (!uri) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ RefPtr<NullPrincipal> nullPrincipal =
|
||||||
|
+ NullPrincipal::CreateWithoutOriginAttributes();
|
||||||
|
+ if (!nullPrincipal) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nsCOMPtr<Document> doc;
|
||||||
|
+ nsresult rv =
|
||||||
|
+ NS_NewDOMDocument(getter_AddRefs(doc), NS_LITERAL_STRING(""), NS_LITERAL_STRING(""), nullptr, uri, uri,
|
||||||
|
+ nullPrincipal, true, nullptr, aFlavor);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ return nullptr;
|
||||||
|
+ }
|
||||||
|
+ return doc.forget();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* static */
|
||||||
|
nsresult nsContentUtils::SetNodeTextContent(nsIContent* aContent,
|
||||||
|
const nsAString& aValue,
|
||||||
|
bool aTryReuse) {
|
||||||
|
diff -r 3476387362fb -r b067b0d3670b dom/base/nsContentUtils.h
|
||||||
|
--- a/dom/base/nsContentUtils.h Fri Oct 23 12:48:49 2020 +0000
|
||||||
|
+++ b/dom/base/nsContentUtils.h Fri Oct 23 12:48:52 2020 +0000
|
||||||
|
@@ -1831,6 +1831,25 @@
|
||||||
|
uint32_t aWrapCol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * Creates a 'loaded-as-data' HTML document that takes that principal,
|
||||||
|
+ * script global, and URL from the argument, which may be null.
|
||||||
|
+ */
|
||||||
|
+ static already_AddRefed<Document> CreateInertHTMLDocument(
|
||||||
|
+ const Document* aTemplate);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Creates a 'loaded-as-data' XML document that takes that principal,
|
||||||
|
+ * script global, and URL from the argument, which may be null.
|
||||||
|
+ */
|
||||||
|
+ static already_AddRefed<Document> CreateInertXMLDocument(
|
||||||
|
+ const Document* aTemplate);
|
||||||
|
+
|
||||||
|
+ private:
|
||||||
|
+ static already_AddRefed<Document> CreateInertDocument(
|
||||||
|
+ const Document* aTemplate, DocumentFlavor aFlavor);
|
||||||
|
+
|
||||||
|
+ public:
|
||||||
|
+ /**
|
||||||
|
* Sets the text contents of a node by replacing all existing children
|
||||||
|
* with a single text child.
|
||||||
|
*
|
||||||
|
diff -r 3476387362fb -r b067b0d3670b editor/libeditor/HTMLEditorDataTransfer.cpp
|
||||||
|
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp Fri Oct 23 12:48:49 2020 +0000
|
||||||
|
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp Fri Oct 23 12:48:52 2020 +0000
|
||||||
|
@@ -3039,8 +3039,13 @@
|
||||||
|
bool aTrustedInput) {
|
||||||
|
nsAutoScriptBlockerSuppressNodeRemoved autoBlocker;
|
||||||
|
|
||||||
|
- RefPtr<DocumentFragment> fragment = new (aTargetDocument->NodeInfoManager())
|
||||||
|
- DocumentFragment(aTargetDocument->NodeInfoManager());
|
||||||
|
+ nsCOMPtr<Document> doc =
|
||||||
|
+ nsContentUtils::CreateInertHTMLDocument(aTargetDocument);
|
||||||
|
+ if (!doc) {
|
||||||
|
+ return NS_ERROR_FAILURE;
|
||||||
|
+ }
|
||||||
|
+ RefPtr<DocumentFragment> fragment =
|
||||||
|
+ new (doc->NodeInfoManager()) DocumentFragment(doc->NodeInfoManager());
|
||||||
|
nsresult rv = nsContentUtils::ParseFragmentHTML(
|
||||||
|
aFragStr, fragment,
|
||||||
|
aContextLocalName ? aContextLocalName : nsGkAtoms::body,
|
||||||
|
diff -r 3476387362fb -r b067b0d3670b parser/html/nsParserUtils.cpp
|
||||||
|
--- a/parser/html/nsParserUtils.cpp Fri Oct 23 12:48:49 2020 +0000
|
||||||
|
+++ b/parser/html/nsParserUtils.cpp Fri Oct 23 12:48:52 2020 +0000
|
||||||
|
@@ -45,17 +45,13 @@
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsParserUtils::Sanitize(const nsAString& aFromStr, uint32_t aFlags,
|
||||||
|
nsAString& aToStr) {
|
||||||
|
- nsCOMPtr<nsIURI> uri;
|
||||||
|
- NS_NewURI(getter_AddRefs(uri), "about:blank");
|
||||||
|
- nsCOMPtr<nsIPrincipal> principal =
|
||||||
|
- mozilla::NullPrincipal::CreateWithoutOriginAttributes();
|
||||||
|
- RefPtr<Document> document;
|
||||||
|
- nsresult rv = NS_NewDOMDocument(getter_AddRefs(document), EmptyString(),
|
||||||
|
- EmptyString(), nullptr, uri, uri, principal,
|
||||||
|
- true, nullptr, DocumentFlavorHTML);
|
||||||
|
- NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
+ RefPtr<Document> document = nsContentUtils::CreateInertHTMLDocument(nullptr);
|
||||||
|
|
||||||
|
- rv = nsContentUtils::ParseDocumentHTML(aFromStr, document, false);
|
||||||
|
+ if (!document) {
|
||||||
|
+ return NS_ERROR_FAILURE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nsresult rv = nsContentUtils::ParseDocumentHTML(aFromStr, document, false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsTreeSanitizer sanitizer(aFlags);
|
||||||
99
CVE-2020-26956-3.patch
Normal file
99
CVE-2020-26956-3.patch
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Henri Sivonen <hsivonen@hsivonen.fi>
|
||||||
|
# Date 1605719936 0
|
||||||
|
# Wed Nov 18 17:18:56 2020 +0000
|
||||||
|
# Node ID 782446e715644da3ca8226d0c3413e3fafb69d6f
|
||||||
|
# Parent 42be1816b3857a3962cd0ec4be551830b6639aee
|
||||||
|
Bug 1666300 test - Test SVG style sanitization on paste. r=smaug
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93634
|
||||||
|
|
||||||
|
diff -r 42be1816b385 -r 782446e71564 editor/libeditor/tests/file_sanitizer_on_paste.sjs
|
||||||
|
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||||
|
+++ b/editor/libeditor/tests/file_sanitizer_on_paste.sjs Wed Nov 18 17:18:56 2020 +0000
|
||||||
|
@@ -0,0 +1,16 @@
|
||||||
|
+function handleRequest(request, response)
|
||||||
|
+{
|
||||||
|
+ if (request.queryString.indexOf("report") != -1) {
|
||||||
|
+ response.setHeader("Content-Type", "text/javascript", false);
|
||||||
|
+ if (getState("loaded") == "loaded") {
|
||||||
|
+ response.write("ok(false, 'There was an attempt to preload the image.');");
|
||||||
|
+ } else {
|
||||||
|
+ response.write("ok(true, 'There was no attempt to preload the image.');");
|
||||||
|
+ }
|
||||||
|
+ response.write("SimpleTest.finish();");
|
||||||
|
+ } else {
|
||||||
|
+ setState("loaded", "loaded");
|
||||||
|
+ response.setHeader("Content-Type", "image/svg", false);
|
||||||
|
+ response.write("<svg xmlns='http://www.w3.org/2000/svg'>Not supposed to load this</svg>");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff -r 42be1816b385 -r 782446e71564 editor/libeditor/tests/mochitest.ini
|
||||||
|
--- a/editor/libeditor/tests/mochitest.ini Wed Dec 16 10:40:06 2020 +0200
|
||||||
|
+++ b/editor/libeditor/tests/mochitest.ini Wed Nov 18 17:18:56 2020 +0000
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
file_bug966155.html
|
||||||
|
file_bug966552.html
|
||||||
|
file_select_all_without_body.html
|
||||||
|
+ file_sanitizer_on_paste.sjs
|
||||||
|
green.png
|
||||||
|
spellcheck.js
|
||||||
|
|
||||||
|
@@ -305,3 +306,4 @@
|
||||||
|
[test_selection_move_commands.html]
|
||||||
|
[test_pasteImgTextarea.html]
|
||||||
|
[test_execCommandPaste_noTarget.html]
|
||||||
|
+[test_sanitizer_on_paste.html]
|
||||||
|
diff -r 42be1816b385 -r 782446e71564 editor/libeditor/tests/test_sanitizer_on_paste.html
|
||||||
|
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||||
|
+++ b/editor/libeditor/tests/test_sanitizer_on_paste.html Wed Nov 18 17:18:56 2020 +0000
|
||||||
|
@@ -0,0 +1,48 @@
|
||||||
|
+<!DOCTYPE HTML>
|
||||||
|
+<html>
|
||||||
|
+<head>
|
||||||
|
+ <meta charset="utf-8">
|
||||||
|
+ <title>Test pasting table rows</title>
|
||||||
|
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||||
|
+</head>
|
||||||
|
+<body>
|
||||||
|
+<textarea></textarea>
|
||||||
|
+<div contenteditable="true">Paste target</div>
|
||||||
|
+<script>
|
||||||
|
+ SimpleTest.waitForExplicitFinish();
|
||||||
|
+ function fail() {
|
||||||
|
+ ok(false, "Should not run event handlers.");
|
||||||
|
+ }
|
||||||
|
+ document.addEventListener('copy', ev => {
|
||||||
|
+ dump("IN LISTENER\n");
|
||||||
|
+ const payload = `<svg><style><image href=file_sanitizer_on_paste.sjs onerror=fail() onload=fail()>`
|
||||||
|
+
|
||||||
|
+ ev.preventDefault();
|
||||||
|
+ ev.clipboardData.setData('text/html', payload);
|
||||||
|
+ ev.clipboardData.setData('text/plain', payload);
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ document.getElementsByTagName("textarea")[0].focus();
|
||||||
|
+ synthesizeKey("c", { accelKey: true } /* aEvent*/);
|
||||||
|
+
|
||||||
|
+ let div = document.getElementsByTagName("div")[0];
|
||||||
|
+ div.focus();
|
||||||
|
+ synthesizeKey("v", { accelKey: true } /* aEvent*/);
|
||||||
|
+
|
||||||
|
+ let svg = div.firstChild;
|
||||||
|
+ is(svg.nodeName, "svg", "Node name should be svg");
|
||||||
|
+
|
||||||
|
+ let style = svg.firstChild;
|
||||||
|
+ if (style) {
|
||||||
|
+ is(style.firstChild, null, "Style should not have child nodes.");
|
||||||
|
+ } else {
|
||||||
|
+ ok(false, "Should have gotten a node.");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ var s = document.createElement("script");
|
||||||
|
+ s.src = "file_sanitizer_on_paste.sjs?report=1";
|
||||||
|
+ document.body.appendChild(s);
|
||||||
|
+</script>
|
||||||
|
+</body>
|
||||||
|
\ No newline at end of file
|
||||||
33
CVE-2020-26957.patch
Normal file
33
CVE-2020-26957.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Agi Sferro <agi@sferro.dev>
|
||||||
|
# Date 1602608252 0
|
||||||
|
# Tue Oct 13 16:57:32 2020 +0000
|
||||||
|
# Node ID 1aa2dc4b280e4ac1d5d5742e1923d5d39c04c102
|
||||||
|
# Parent 943130e5f28ed6ee3e6b8bbf0f9c9f60fb5a7053
|
||||||
|
Bug 1667179 - Initialize OneCRL when GeckoView starts. r=snorp,jcj
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93250
|
||||||
|
|
||||||
|
diff -r 943130e5f28e -r 1aa2dc4b280e mobile/android/chrome/geckoview/geckoview.js
|
||||||
|
--- a/mobile/android/chrome/geckoview/geckoview.js Tue Oct 13 16:59:30 2020 +0000
|
||||||
|
+++ b/mobile/android/chrome/geckoview/geckoview.js Tue Oct 13 16:57:32 2020 +0000
|
||||||
|
@@ -18,6 +18,8 @@
|
||||||
|
GeckoViewSettings: "resource://gre/modules/GeckoViewSettings.jsm",
|
||||||
|
GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm",
|
||||||
|
HistogramStopwatch: "resource://gre/modules/GeckoViewTelemetry.jsm",
|
||||||
|
+ RemoteSecuritySettings:
|
||||||
|
+ "resource://gre/modules/psm/RemoteSecuritySettings.jsm",
|
||||||
|
});
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyGetter(this, "WindowEventDispatcher", () =>
|
||||||
|
@@ -610,6 +612,10 @@
|
||||||
|
Services.obs.notifyObservers(window, "extensions-late-startup");
|
||||||
|
});
|
||||||
|
|
||||||
|
+ InitLater(() => {
|
||||||
|
+ RemoteSecuritySettings.init();
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
// This should always go last, since the idle tasks (except for the ones with
|
||||||
|
// timeouts) should execute in order. Note that this observer notification is
|
||||||
|
// not guaranteed to fire, since the window could close before we get here.
|
||||||
768
CVE-2020-26958.patch
Normal file
768
CVE-2020-26958.patch
Normal file
@ -0,0 +1,768 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Andrew Sutherland <asutherland@asutherland.org>
|
||||||
|
# Date 1603887323 0
|
||||||
|
# Wed Oct 28 12:15:23 2020 +0000
|
||||||
|
# Node ID 6873589e0ede3c11bc48243be67c3d51e214873f
|
||||||
|
# Parent e6a1286e25b70d36a1e251fb056596181565d839
|
||||||
|
Bug 1669355 - Refactor MIME type warnings into base class. r=necko-reviewers,valentin
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93906
|
||||||
|
|
||||||
|
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/HttpBaseChannel.cpp
|
||||||
|
--- a/netwerk/protocol/http/HttpBaseChannel.cpp 2020-07-21 06:49:41.000000000 +0800
|
||||||
|
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp 2021-01-06 11:26:44.608483314 +0800
|
||||||
|
@@ -24,10 +24,12 @@
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
|
#include "mozilla/Services.h"
|
||||||
|
#include "mozilla/StaticPrefs_browser.h"
|
||||||
|
+#include "mozilla/StaticPrefs_security.h"
|
||||||
|
#include "mozilla/Telemetry.h"
|
||||||
|
#include "mozilla/Tokenizer.h"
|
||||||
|
#include "mozilla/dom/BrowsingContext.h"
|
||||||
|
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||||
|
+#include "mozilla/dom/Document.h"
|
||||||
|
#include "mozilla/dom/Performance.h"
|
||||||
|
#include "mozilla/dom/PerformanceStorage.h"
|
||||||
|
#include "mozilla/dom/WindowGlobalParent.h"
|
||||||
|
@@ -2385,6 +2387,354 @@ nsresult HttpBaseChannel::ComputeCrossOr
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+enum class Report { Error, Warning };
|
||||||
|
+
|
||||||
|
+// Helper Function to report messages to the console when the loaded
|
||||||
|
+// script had a wrong MIME type.
|
||||||
|
+void ReportMimeTypeMismatch(HttpBaseChannel* aChannel, const char* aMessageName,
|
||||||
|
+ nsIURI* aURI, const nsACString& aContentType,
|
||||||
|
+ Report report) {
|
||||||
|
+ NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
|
||||||
|
+ NS_ConvertUTF8toUTF16 contentType(aContentType);
|
||||||
|
+
|
||||||
|
+ aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
|
||||||
|
+ report == Report::Warning, spec, contentType);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Check and potentially enforce X-Content-Type-Options: nosniff
|
||||||
|
+nsresult ProcessXCTO(HttpBaseChannel* aChannel, nsIURI* aURI,
|
||||||
|
+ nsHttpResponseHead* aResponseHead,
|
||||||
|
+ nsILoadInfo* aLoadInfo) {
|
||||||
|
+ if (!aURI || !aResponseHead || !aLoadInfo) {
|
||||||
|
+ // if there is no uri, no response head or no loadInfo, then there is
|
||||||
|
+ // nothing to do
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // 1) Query the XCTO header and check if 'nosniff' is the first value.
|
||||||
|
+ nsAutoCString contentTypeOptionsHeader;
|
||||||
|
+ if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
|
||||||
|
+ // if failed to get XCTO header, then there is nothing to do.
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // let's compare the header (ignoring case)
|
||||||
|
+ // e.g. "NoSniFF" -> "nosniff"
|
||||||
|
+ // if it's not 'nosniff' then there is nothing to do here
|
||||||
|
+ if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
|
||||||
|
+ // since we are getting here, the XCTO header was sent;
|
||||||
|
+ // a non matching value most likely means a mistake happenend;
|
||||||
|
+ // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
|
||||||
|
+ AutoTArray<nsString, 1> params;
|
||||||
|
+ CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
|
||||||
|
+ RefPtr<dom::Document> doc;
|
||||||
|
+ aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
|
||||||
|
+ nsContentUtils::ReportToConsole(
|
||||||
|
+ nsIScriptError::warningFlag, NS_LITERAL_CSTRING("XCTO"), doc,
|
||||||
|
+ nsContentUtils::eSECURITY_PROPERTIES, "XCTOHeaderValueMissing", params);
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // 2) Query the content type from the channel
|
||||||
|
+ nsAutoCString contentType;
|
||||||
|
+ aResponseHead->ContentType(contentType);
|
||||||
|
+
|
||||||
|
+ // 3) Compare the expected MIME type with the actual type
|
||||||
|
+ if (aLoadInfo->GetExternalContentPolicyType() ==
|
||||||
|
+ nsIContentPolicy::TYPE_STYLESHEET) {
|
||||||
|
+ if (contentType.EqualsLiteral(TEXT_CSS)) {
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+ ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
|
||||||
|
+ Report::Error);
|
||||||
|
+ return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (aLoadInfo->GetExternalContentPolicyType() ==
|
||||||
|
+ nsIContentPolicy::TYPE_SCRIPT) {
|
||||||
|
+ if (nsContentUtils::IsJavascriptMIMEType(
|
||||||
|
+ NS_ConvertUTF8toUTF16(contentType))) {
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+ ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
|
||||||
|
+ Report::Error);
|
||||||
|
+ return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ auto policyType = aLoadInfo->GetExternalContentPolicyType();
|
||||||
|
+ if ((policyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||||
|
+ policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) &&
|
||||||
|
+ gHttpHandler->IsDocumentNosniffEnabled()) {
|
||||||
|
+ // If the header XCTO nosniff is set for any browsing context, then
|
||||||
|
+ // we set the skipContentSniffing flag on the Loadinfo. Within
|
||||||
|
+ // GetMIMETypeFromContent we then bail early and do not do any sniffing.
|
||||||
|
+ aLoadInfo->SetSkipContentSniffing(true);
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Ensure that a load of type script has correct MIME type
|
||||||
|
+nsresult EnsureMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
|
||||||
|
+ nsHttpResponseHead* aResponseHead,
|
||||||
|
+ nsILoadInfo* aLoadInfo) {
|
||||||
|
+ if (!aURI || !aResponseHead || !aLoadInfo) {
|
||||||
|
+ // if there is no uri, no response head or no loadInfo, then there is
|
||||||
|
+ // nothing to do
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (aLoadInfo->GetExternalContentPolicyType() !=
|
||||||
|
+ nsIContentPolicy::TYPE_SCRIPT) {
|
||||||
|
+ // if this is not a script load, then there is nothing to do
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nsAutoCString contentType;
|
||||||
|
+ aResponseHead->ContentType(contentType);
|
||||||
|
+ NS_ConvertUTF8toUTF16 typeString(contentType);
|
||||||
|
+
|
||||||
|
+ if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
|
||||||
|
+ // script load has type script
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (aLoadInfo->InternalContentPolicyType()) {
|
||||||
|
+ case nsIContentPolicy::TYPE_SCRIPT:
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_MODULE:
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
|
||||||
|
+ break;
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_WORKER:
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
|
||||||
|
+ break;
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
|
||||||
|
+ break;
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
|
||||||
|
+ break;
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
|
||||||
|
+ case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ MOZ_ASSERT_UNREACHABLE("unexpected script type");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bool isPrivateWin = aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
|
||||||
|
+ bool isSameOrigin = false;
|
||||||
|
+ aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI, isPrivateWin,
|
||||||
|
+ &isSameOrigin);
|
||||||
|
+ if (isSameOrigin) {
|
||||||
|
+ // same origin
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
|
||||||
|
+ } else {
|
||||||
|
+ bool cors = false;
|
||||||
|
+ nsAutoCString corsOrigin;
|
||||||
|
+ nsresult rv = aResponseHead->GetHeader(
|
||||||
|
+ nsHttp::ResolveAtom("Access-Control-Allow-Origin"), corsOrigin);
|
||||||
|
+ if (NS_SUCCEEDED(rv)) {
|
||||||
|
+ if (corsOrigin.Equals("*")) {
|
||||||
|
+ cors = true;
|
||||||
|
+ } else {
|
||||||
|
+ nsCOMPtr<nsIURI> corsOriginURI;
|
||||||
|
+ rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
|
||||||
|
+ if (NS_SUCCEEDED(rv)) {
|
||||||
|
+ bool isPrivateWin =
|
||||||
|
+ aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
|
||||||
|
+ bool isSameOrigin = false;
|
||||||
|
+ aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(
|
||||||
|
+ corsOriginURI, isPrivateWin, &isSameOrigin);
|
||||||
|
+ if (isSameOrigin) {
|
||||||
|
+ cors = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (cors) {
|
||||||
|
+ // cors origin
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
|
||||||
|
+ } else {
|
||||||
|
+ // cross origin
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bool block = false;
|
||||||
|
+ if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
|
||||||
|
+ // script load has type image
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
|
||||||
|
+ block = true;
|
||||||
|
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("audio/"))) {
|
||||||
|
+ // script load has type audio
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
|
||||||
|
+ block = true;
|
||||||
|
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("video/"))) {
|
||||||
|
+ // script load has type video
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
|
||||||
|
+ block = true;
|
||||||
|
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/csv"))) {
|
||||||
|
+ // script load has type text/csv
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
|
||||||
|
+ block = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (block) {
|
||||||
|
+ // Do not block the load if the feature is not enabled.
|
||||||
|
+ if (!StaticPrefs::security_block_script_with_wrong_mime()) {
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
|
||||||
|
+ contentType, Report::Error);
|
||||||
|
+ return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
|
||||||
|
+ // script load has type text/plain
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
|
||||||
|
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/xml"))) {
|
||||||
|
+ // script load has type text/xml
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
|
||||||
|
+ } else if (StringBeginsWith(contentType,
|
||||||
|
+ NS_LITERAL_CSTRING("application/octet-stream"))) {
|
||||||
|
+ // script load has type application/octet-stream
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
|
||||||
|
+ } else if (StringBeginsWith(contentType,
|
||||||
|
+ NS_LITERAL_CSTRING("application/xml"))) {
|
||||||
|
+ // script load has type application/xml
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
|
||||||
|
+ } else if (StringBeginsWith(contentType,
|
||||||
|
+ NS_LITERAL_CSTRING("application/json"))) {
|
||||||
|
+ // script load has type application/json
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
|
||||||
|
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/json"))) {
|
||||||
|
+ // script load has type text/json
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
|
||||||
|
+ } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/html"))) {
|
||||||
|
+ // script load has type text/html
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
|
||||||
|
+ } else if (contentType.IsEmpty()) {
|
||||||
|
+ // script load has no type
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
|
||||||
|
+ } else {
|
||||||
|
+ // script load has unknown type
|
||||||
|
+ AccumulateCategorical(
|
||||||
|
+ Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // We restrict importScripts() in worker code to JavaScript MIME types.
|
||||||
|
+ nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
|
||||||
|
+ if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS) {
|
||||||
|
+ // Do not block the load if the feature is not enabled.
|
||||||
|
+ if (!StaticPrefs::security_block_importScripts_with_wrong_mime()) {
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
|
||||||
|
+ aURI, contentType, Report::Error);
|
||||||
|
+ return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
|
||||||
|
+ internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
|
||||||
|
+ // Do not block the load if the feature is not enabled.
|
||||||
|
+ if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
|
||||||
|
+ contentType, Report::Error);
|
||||||
|
+ return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // ES6 modules require a strict MIME type check.
|
||||||
|
+ if (internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
|
||||||
|
+ internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD) {
|
||||||
|
+ ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
|
||||||
|
+ contentType, Report::Error);
|
||||||
|
+ return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Warn when a load of type script uses a wrong MIME type and
|
||||||
|
+// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
|
||||||
|
+void WarnWrongMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
|
||||||
|
+ nsHttpResponseHead* aResponseHead,
|
||||||
|
+ nsILoadInfo* aLoadInfo) {
|
||||||
|
+ if (!aURI || !aResponseHead || !aLoadInfo) {
|
||||||
|
+ // If there is no uri, no response head or no loadInfo, then there is
|
||||||
|
+ // nothing to do.
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (aLoadInfo->GetExternalContentPolicyType() !=
|
||||||
|
+ nsIContentPolicy::TYPE_SCRIPT) {
|
||||||
|
+ // If this is not a script load, then there is nothing to do.
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bool succeeded;
|
||||||
|
+ MOZ_ALWAYS_SUCCEEDS(aChannel->GetRequestSucceeded(&succeeded));
|
||||||
|
+ if (!succeeded) {
|
||||||
|
+ // Do not warn for failed loads: HTTP error pages are usually in HTML.
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ nsAutoCString contentType;
|
||||||
|
+ aResponseHead->ContentType(contentType);
|
||||||
|
+ NS_ConvertUTF8toUTF16 typeString(contentType);
|
||||||
|
+ if (!nsContentUtils::IsJavascriptMIMEType(typeString)) {
|
||||||
|
+ ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
|
||||||
|
+ contentType, Report::Warning);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+nsresult HttpBaseChannel::ValidateMIMEType() {
|
||||||
|
+ nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ return rv;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ return rv;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
|
||||||
|
+ return NS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::SetCookie(const nsACString& aCookieHeader) {
|
||||||
|
if (mLoadFlags & LOAD_ANONYMOUS) return NS_OK;
|
||||||
|
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/HttpBaseChannel.h
|
||||||
|
--- a/netwerk/protocol/http/HttpBaseChannel.h 2020-07-21 04:53:32.000000000 +0800
|
||||||
|
+++ b/netwerk/protocol/http/HttpBaseChannel.h 2021-01-06 10:53:17.326264473 +0800
|
||||||
|
@@ -610,6 +610,8 @@ class HttpBaseChannel : public nsHashPro
|
||||||
|
|
||||||
|
nsresult ComputeCrossOriginOpenerPolicyMismatch();
|
||||||
|
|
||||||
|
+ nsresult ValidateMIMEType();
|
||||||
|
+
|
||||||
|
friend class PrivateBrowsingChannel<HttpBaseChannel>;
|
||||||
|
friend class InterceptFailedOnStop;
|
||||||
|
|
||||||
|
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/InterceptedHttpChannel.cpp
|
||||||
|
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp 2020-07-21 06:49:41.000000000 +0800
|
||||||
|
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp 2021-01-06 10:53:17.326264473 +0800
|
||||||
|
@@ -1046,6 +1046,12 @@ InterceptedHttpChannel::OnStartRequest(n
|
||||||
|
Cancel(mStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ rv = ValidateMIMEType();
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ mStatus = rv;
|
||||||
|
+ Cancel(mStatus);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
mOnStartRequestCalled = true;
|
||||||
|
if (mListener) {
|
||||||
|
return mListener->OnStartRequest(this);
|
||||||
|
diff -r e6a1286e25b7 -r 6873589e0ede netwerk/protocol/http/nsHttpChannel.cpp
|
||||||
|
--- a/netwerk/protocol/http/nsHttpChannel.cpp 2021-01-06 10:53:17.330264533 +0800
|
||||||
|
+++ b/netwerk/protocol/http/nsHttpChannel.cpp 2021-01-06 11:10:19.257650688 +0800
|
||||||
|
@@ -1485,339 +1485,6 @@ HttpTrafficCategory nsHttpChannel::Creat
|
||||||
|
NS_UsePrivateBrowsing(this), isSystemPrincipal, isThirdParty, cos, tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
-enum class Report { Error, Warning };
|
||||||
|
-
|
||||||
|
-// Helper Function to report messages to the console when the loaded
|
||||||
|
-// script had a wrong MIME type.
|
||||||
|
-void ReportMimeTypeMismatch(nsHttpChannel* aChannel, const char* aMessageName,
|
||||||
|
- nsIURI* aURI, const nsACString& aContentType,
|
||||||
|
- Report report) {
|
||||||
|
- NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
|
||||||
|
- NS_ConvertUTF8toUTF16 contentType(aContentType);
|
||||||
|
-
|
||||||
|
- aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
|
||||||
|
- report == Report::Warning, spec, contentType);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-// Check and potentially enforce X-Content-Type-Options: nosniff
|
||||||
|
-nsresult ProcessXCTO(nsHttpChannel* aChannel, nsIURI* aURI,
|
||||||
|
- nsHttpResponseHead* aResponseHead,
|
||||||
|
- nsILoadInfo* aLoadInfo) {
|
||||||
|
- if (!aURI || !aResponseHead || !aLoadInfo) {
|
||||||
|
- // if there is no uri, no response head or no loadInfo, then there is
|
||||||
|
- // nothing to do
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // 1) Query the XCTO header and check if 'nosniff' is the first value.
|
||||||
|
- nsAutoCString contentTypeOptionsHeader;
|
||||||
|
- if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
|
||||||
|
- // if failed to get XCTO header, then there is nothing to do.
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // let's compare the header (ignoring case)
|
||||||
|
- // e.g. "NoSniFF" -> "nosniff"
|
||||||
|
- // if it's not 'nosniff' then there is nothing to do here
|
||||||
|
- if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
|
||||||
|
- // since we are getting here, the XCTO header was sent;
|
||||||
|
- // a non matching value most likely means a mistake happenend;
|
||||||
|
- // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
|
||||||
|
- AutoTArray<nsString, 1> params;
|
||||||
|
- CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
|
||||||
|
- RefPtr<Document> doc;
|
||||||
|
- aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
|
||||||
|
- nsContentUtils::ReportToConsole(
|
||||||
|
- nsIScriptError::warningFlag, NS_LITERAL_CSTRING("XCTO"), doc,
|
||||||
|
- nsContentUtils::eSECURITY_PROPERTIES, "XCTOHeaderValueMissing", params);
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // 2) Query the content type from the channel
|
||||||
|
- nsAutoCString contentType;
|
||||||
|
- aResponseHead->ContentType(contentType);
|
||||||
|
-
|
||||||
|
- // 3) Compare the expected MIME type with the actual type
|
||||||
|
- if (aLoadInfo->GetExternalContentPolicyType() ==
|
||||||
|
- nsIContentPolicy::TYPE_STYLESHEET) {
|
||||||
|
- if (contentType.EqualsLiteral(TEXT_CSS)) {
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
- ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
|
||||||
|
- Report::Error);
|
||||||
|
- return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (aLoadInfo->GetExternalContentPolicyType() ==
|
||||||
|
- nsIContentPolicy::TYPE_SCRIPT) {
|
||||||
|
- if (nsContentUtils::IsJavascriptMIMEType(
|
||||||
|
- NS_ConvertUTF8toUTF16(contentType))) {
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
- ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
|
||||||
|
- Report::Error);
|
||||||
|
- return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- auto policyType = aLoadInfo->GetExternalContentPolicyType();
|
||||||
|
- if ((policyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||||
|
- policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) &&
|
||||||
|
- gHttpHandler->IsDocumentNosniffEnabled()) {
|
||||||
|
- // If the header XCTO nosniff is set for any browsing context, then
|
||||||
|
- // we set the skipContentSniffing flag on the Loadinfo. Within
|
||||||
|
- // GetMIMETypeFromContent we then bail early and do not do any sniffing.
|
||||||
|
- aLoadInfo->SetSkipContentSniffing(true);
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return NS_OK;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-// Ensure that a load of type script has correct MIME type
|
||||||
|
-nsresult EnsureMIMEOfScript(nsHttpChannel* aChannel, nsIURI* aURI,
|
||||||
|
- nsHttpResponseHead* aResponseHead,
|
||||||
|
- nsILoadInfo* aLoadInfo) {
|
||||||
|
- if (!aURI || !aResponseHead || !aLoadInfo) {
|
||||||
|
- // if there is no uri, no response head or no loadInfo, then there is
|
||||||
|
- // nothing to do
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (aLoadInfo->GetExternalContentPolicyType() !=
|
||||||
|
- nsIContentPolicy::TYPE_SCRIPT) {
|
||||||
|
- // if this is not a script load, then there is nothing to do
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- nsAutoCString contentType;
|
||||||
|
- aResponseHead->ContentType(contentType);
|
||||||
|
- NS_ConvertUTF8toUTF16 typeString(contentType);
|
||||||
|
-
|
||||||
|
- if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
|
||||||
|
- // script load has type script
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- switch (aLoadInfo->InternalContentPolicyType()) {
|
||||||
|
- case nsIContentPolicy::TYPE_SCRIPT:
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_MODULE:
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
|
||||||
|
- break;
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_WORKER:
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
|
||||||
|
- break;
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
|
||||||
|
- break;
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
|
||||||
|
- break;
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
|
||||||
|
- case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- MOZ_ASSERT_UNREACHABLE("unexpected script type");
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bool isPrivateWin = aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
|
||||||
|
- bool isSameOrigin = false;
|
||||||
|
- aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI, isPrivateWin,
|
||||||
|
- &isSameOrigin);
|
||||||
|
- if (isSameOrigin) {
|
||||||
|
- // same origin
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
|
||||||
|
- } else {
|
||||||
|
- bool cors = false;
|
||||||
|
- nsAutoCString corsOrigin;
|
||||||
|
- nsresult rv = aResponseHead->GetHeader(
|
||||||
|
- nsHttp::ResolveAtom("Access-Control-Allow-Origin"), corsOrigin);
|
||||||
|
- if (NS_SUCCEEDED(rv)) {
|
||||||
|
- if (corsOrigin.Equals("*")) {
|
||||||
|
- cors = true;
|
||||||
|
- } else {
|
||||||
|
- nsCOMPtr<nsIURI> corsOriginURI;
|
||||||
|
- rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
|
||||||
|
- if (NS_SUCCEEDED(rv)) {
|
||||||
|
- bool isPrivateWin =
|
||||||
|
- aLoadInfo->GetOriginAttributes().mPrivateBrowsingId > 0;
|
||||||
|
- bool isSameOrigin = false;
|
||||||
|
- aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(
|
||||||
|
- corsOriginURI, isPrivateWin, &isSameOrigin);
|
||||||
|
- if (isSameOrigin) {
|
||||||
|
- cors = true;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (cors) {
|
||||||
|
- // cors origin
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
|
||||||
|
- } else {
|
||||||
|
- // cross origin
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bool block = false;
|
||||||
|
- if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
|
||||||
|
- // script load has type image
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
|
||||||
|
- block = true;
|
||||||
|
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("audio/"))) {
|
||||||
|
- // script load has type audio
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
|
||||||
|
- block = true;
|
||||||
|
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("video/"))) {
|
||||||
|
- // script load has type video
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
|
||||||
|
- block = true;
|
||||||
|
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/csv"))) {
|
||||||
|
- // script load has type text/csv
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
|
||||||
|
- block = true;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (block) {
|
||||||
|
- // Do not block the load if the feature is not enabled.
|
||||||
|
- if (!StaticPrefs::security_block_script_with_wrong_mime()) {
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
|
||||||
|
- contentType, Report::Error);
|
||||||
|
- return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/plain"))) {
|
||||||
|
- // script load has type text/plain
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
|
||||||
|
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/xml"))) {
|
||||||
|
- // script load has type text/xml
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
|
||||||
|
- } else if (StringBeginsWith(contentType,
|
||||||
|
- NS_LITERAL_CSTRING("application/octet-stream"))) {
|
||||||
|
- // script load has type application/octet-stream
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
|
||||||
|
- } else if (StringBeginsWith(contentType,
|
||||||
|
- NS_LITERAL_CSTRING("application/xml"))) {
|
||||||
|
- // script load has type application/xml
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
|
||||||
|
- } else if (StringBeginsWith(contentType,
|
||||||
|
- NS_LITERAL_CSTRING("application/json"))) {
|
||||||
|
- // script load has type application/json
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
|
||||||
|
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/json"))) {
|
||||||
|
- // script load has type text/json
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
|
||||||
|
- } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("text/html"))) {
|
||||||
|
- // script load has type text/html
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
|
||||||
|
- } else if (contentType.IsEmpty()) {
|
||||||
|
- // script load has no type
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
|
||||||
|
- } else {
|
||||||
|
- // script load has unknown type
|
||||||
|
- AccumulateCategorical(
|
||||||
|
- Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // We restrict importScripts() in worker code to JavaScript MIME types.
|
||||||
|
- nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
|
||||||
|
- if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS) {
|
||||||
|
- // Do not block the load if the feature is not enabled.
|
||||||
|
- if (!StaticPrefs::security_block_importScripts_with_wrong_mime()) {
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
|
||||||
|
- aURI, contentType, Report::Error);
|
||||||
|
- return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
|
||||||
|
- internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
|
||||||
|
- // Do not block the load if the feature is not enabled.
|
||||||
|
- if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
|
||||||
|
- return NS_OK;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
|
||||||
|
- contentType, Report::Error);
|
||||||
|
- return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // ES6 modules require a strict MIME type check.
|
||||||
|
- if (internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
|
||||||
|
- internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD) {
|
||||||
|
- ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
|
||||||
|
- contentType, Report::Error);
|
||||||
|
- return NS_ERROR_CORRUPTED_CONTENT;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return NS_OK;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-// Warn when a load of type script uses a wrong MIME type and
|
||||||
|
-// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
|
||||||
|
-void WarnWrongMIMEOfScript(nsHttpChannel* aChannel, nsIURI* aURI,
|
||||||
|
- nsHttpResponseHead* aResponseHead,
|
||||||
|
- nsILoadInfo* aLoadInfo) {
|
||||||
|
- if (!aURI || !aResponseHead || !aLoadInfo) {
|
||||||
|
- // If there is no uri, no response head or no loadInfo, then there is
|
||||||
|
- // nothing to do.
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (aLoadInfo->GetExternalContentPolicyType() !=
|
||||||
|
- nsIContentPolicy::TYPE_SCRIPT) {
|
||||||
|
- // If this is not a script load, then there is nothing to do.
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bool succeeded;
|
||||||
|
- MOZ_ALWAYS_SUCCEEDS(aChannel->GetRequestSucceeded(&succeeded));
|
||||||
|
- if (!succeeded) {
|
||||||
|
- // Do not warn for failed loads: HTTP error pages are usually in HTML.
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- nsAutoCString contentType;
|
||||||
|
- aResponseHead->ContentType(contentType);
|
||||||
|
- NS_ConvertUTF8toUTF16 typeString(contentType);
|
||||||
|
- if (!nsContentUtils::IsJavascriptMIMEType(typeString)) {
|
||||||
|
- ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
|
||||||
|
- contentType, Report::Warning);
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void nsHttpChannel::SetCachedContentType() {
|
||||||
|
if (!mResponseHead) {
|
||||||
|
return;
|
||||||
|
@@ -1913,14 +1580,9 @@ nsresult nsHttpChannel::CallOnStartReque
|
||||||
|
mOnStartRequestCalled = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
- nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
|
||||||
|
- NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
-
|
||||||
|
- rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
|
||||||
|
+ nsresult rv = ValidateMIMEType();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
- WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
|
||||||
|
-
|
||||||
|
// Allow consumers to override our content type
|
||||||
|
if (mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
|
||||||
|
// NOTE: We can have both a txn pump and a cache pump when the cache
|
||||||
63
CVE-2020-26959.patch
Normal file
63
CVE-2020-26959.patch
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Luca Greco <lgreco@mozilla.com>
|
||||||
|
# Date 1603810809 0
|
||||||
|
# Tue Oct 27 15:00:09 2020 +0000
|
||||||
|
# Node ID 8de8cd3371e801d408650f102df04252c846f33d
|
||||||
|
# Parent 5058a78c1008f0917866aa09abff7430bcefa085
|
||||||
|
Bug 1669466 - Change WebRequestService singleton to a StaticRefPtr. r=glandium,mixedpuppy
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D94692
|
||||||
|
|
||||||
|
diff -r 5058a78c1008 -r 8de8cd3371e8 toolkit/components/extensions/webrequest/WebRequestService.cpp
|
||||||
|
--- a/toolkit/components/extensions/webrequest/WebRequestService.cpp Tue Oct 27 15:07:07 2020 +0000
|
||||||
|
+++ b/toolkit/components/extensions/webrequest/WebRequestService.cpp Tue Oct 27 15:00:09 2020 +0000
|
||||||
|
@@ -13,22 +13,14 @@
|
||||||
|
using namespace mozilla::dom;
|
||||||
|
using namespace mozilla::extensions;
|
||||||
|
|
||||||
|
-static WebRequestService* sWeakWebRequestService;
|
||||||
|
-
|
||||||
|
-WebRequestService::~WebRequestService() { sWeakWebRequestService = nullptr; }
|
||||||
|
+static StaticRefPtr<WebRequestService> sWebRequestService;
|
||||||
|
|
||||||
|
/* static */ WebRequestService& WebRequestService::GetSingleton() {
|
||||||
|
- static RefPtr<WebRequestService> instance;
|
||||||
|
- if (!sWeakWebRequestService) {
|
||||||
|
- instance = new WebRequestService();
|
||||||
|
- ClearOnShutdown(&instance);
|
||||||
|
-
|
||||||
|
- // A separate weak instance that we keep a reference to as long as the
|
||||||
|
- // original service is alive, even after our strong reference is cleared to
|
||||||
|
- // allow the service to be destroyed.
|
||||||
|
- sWeakWebRequestService = instance;
|
||||||
|
+ if (!sWebRequestService) {
|
||||||
|
+ sWebRequestService = new WebRequestService();
|
||||||
|
+ ClearOnShutdown(&sWebRequestService);
|
||||||
|
}
|
||||||
|
- return *sWeakWebRequestService;
|
||||||
|
+ return *sWebRequestService;
|
||||||
|
}
|
||||||
|
|
||||||
|
UniquePtr<WebRequestChannelEntry> WebRequestService::RegisterChannel(
|
||||||
|
@@ -56,7 +48,7 @@
|
||||||
|
: mChannelId(aChannel->Id()), mChannel(aChannel) {}
|
||||||
|
|
||||||
|
WebRequestChannelEntry::~WebRequestChannelEntry() {
|
||||||
|
- if (sWeakWebRequestService) {
|
||||||
|
- sWeakWebRequestService->mChannelEntries.Remove(mChannelId);
|
||||||
|
+ if (sWebRequestService) {
|
||||||
|
+ sWebRequestService->mChannelEntries.Remove(mChannelId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff -r 5058a78c1008 -r 8de8cd3371e8 toolkit/components/extensions/webrequest/WebRequestService.h
|
||||||
|
--- a/toolkit/components/extensions/webrequest/WebRequestService.h Tue Oct 27 15:07:07 2020 +0000
|
||||||
|
+++ b/toolkit/components/extensions/webrequest/WebRequestService.h Tue Oct 27 15:00:09 2020 +0000
|
||||||
|
@@ -64,7 +64,7 @@
|
||||||
|
dom::ContentParent* aContentParent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
- ~WebRequestService();
|
||||||
|
+ ~WebRequestService() = default;
|
||||||
|
|
||||||
|
friend ChannelEntry;
|
||||||
|
|
||||||
49
CVE-2020-26960-1.patch
Normal file
49
CVE-2020-26960-1.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Jon Coppeard <jcoppeard@mozilla.com>
|
||||||
|
# Date 1603288236 0
|
||||||
|
# Wed Oct 21 13:50:36 2020 +0000
|
||||||
|
# Node ID 7e223284a9225c66b590aaad671c7448d1ff0b57
|
||||||
|
# Parent dfcb025567da9e33bf724520e0146fef3d776d5f
|
||||||
|
Bug 1670358 - Don't use realloc for shrinking nsTArrays and similar when RelocationStrategy::allowRealloc is false r=sg
|
||||||
|
|
||||||
|
My original patch handled the grow case but not the shrink case. When the
|
||||||
|
current and new allocation sizes are in different size classes jemalloc's
|
||||||
|
realloc will move the allocation when shrinking, not just truncate the existing
|
||||||
|
one.
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D93654
|
||||||
|
|
||||||
|
diff -r dfcb025567da -r 7e223284a922 xpcom/ds/nsTArray-inl.h
|
||||||
|
--- a/xpcom/ds/nsTArray-inl.h Thu Oct 22 07:36:15 2020 +0000
|
||||||
|
+++ b/xpcom/ds/nsTArray-inl.h Wed Oct 21 13:50:36 2020 +0000
|
||||||
|
@@ -259,10 +259,27 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type size = sizeof(Header) + length * aElemSize;
|
||||||
|
- void* ptr = nsTArrayFallibleAllocator::Realloc(mHdr, size);
|
||||||
|
- if (!ptr) {
|
||||||
|
- return;
|
||||||
|
+ void* ptr;
|
||||||
|
+
|
||||||
|
+ if (!RelocationStrategy::allowRealloc) {
|
||||||
|
+ // Malloc() and copy.
|
||||||
|
+ ptr = static_cast<Header*>(nsTArrayFallibleAllocator::Malloc(size));
|
||||||
|
+ if (!ptr) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ RelocationStrategy::RelocateNonOverlappingRegionWithHeader(
|
||||||
|
+ ptr, mHdr, Length(), aElemSize);
|
||||||
|
+
|
||||||
|
+ nsTArrayFallibleAllocator::Free(mHdr);
|
||||||
|
+ } else {
|
||||||
|
+ // Realloc() existing data.
|
||||||
|
+ ptr = nsTArrayFallibleAllocator::Realloc(mHdr, size);
|
||||||
|
+ if (!ptr) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
mHdr = static_cast<Header*>(ptr);
|
||||||
|
mHdr->mCapacity = length;
|
||||||
|
}
|
||||||
136
CVE-2020-26960-2.patch
Normal file
136
CVE-2020-26960-2.patch
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Jon Coppeard <jcoppeard@mozilla.com>
|
||||||
|
# Date 1603288237 0
|
||||||
|
# Wed Oct 21 13:50:37 2020 +0000
|
||||||
|
# Node ID 8a8d7fdc7038fb360d7c50f5943ccafd7f0bb829
|
||||||
|
# Parent 7e223284a9225c66b590aaad671c7448d1ff0b57
|
||||||
|
Bug 1670358 - Add test for shrinking nsTArrays of JS::Heap<T> r=sg
|
||||||
|
|
||||||
|
Depends on D93654
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D94270
|
||||||
|
|
||||||
|
diff -r 7e223284a922 -r 8a8d7fdc7038 xpcom/tests/gtest/TestGCPostBarriers.cpp
|
||||||
|
--- a/xpcom/tests/gtest/TestGCPostBarriers.cpp Wed Oct 21 13:50:36 2020 +0000
|
||||||
|
+++ b/xpcom/tests/gtest/TestGCPostBarriers.cpp Wed Oct 21 13:50:37 2020 +0000
|
||||||
|
@@ -9,6 +9,8 @@
|
||||||
|
* implemented for nsTArrays that contain JavaScript Values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include "mozilla/UniquePtr.h"
|
||||||
|
+
|
||||||
|
#include "jsapi.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
@@ -37,11 +39,13 @@
|
||||||
|
const size_t InitialElements = ElementCount / 10;
|
||||||
|
|
||||||
|
template <class ArrayT>
|
||||||
|
-static void RunTest(JSContext* cx, ArrayT* array) {
|
||||||
|
+static void TestGrow(JSContext* cx) {
|
||||||
|
JS_GC(cx);
|
||||||
|
|
||||||
|
+ auto array = MakeUnique<ArrayT>();
|
||||||
|
ASSERT_TRUE(array != nullptr);
|
||||||
|
- JS_AddExtraGCRootsTracer(cx, TraceArray<ArrayT>, array);
|
||||||
|
+
|
||||||
|
+ JS_AddExtraGCRootsTracer(cx, TraceArray<ArrayT>, array.get());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the array and fill it with new JS objects. With GGC these will be
|
||||||
|
@@ -66,7 +70,8 @@
|
||||||
|
/*
|
||||||
|
* Sanity check that our array contains what we expect.
|
||||||
|
*/
|
||||||
|
- for (size_t i = 0; i < ElementCount; ++i) {
|
||||||
|
+ ASSERT_EQ(array->Length(), ElementCount);
|
||||||
|
+ for (size_t i = 0; i < array->Length(); i++) {
|
||||||
|
RootedObject obj(cx, array->ElementAt(i));
|
||||||
|
ASSERT_TRUE(JS::ObjectIsTenured(obj));
|
||||||
|
ASSERT_TRUE(JS_GetProperty(cx, obj, property, &value));
|
||||||
|
@@ -74,7 +79,54 @@
|
||||||
|
ASSERT_EQ(static_cast<int32_t>(i), value.toInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
- JS_RemoveExtraGCRootsTracer(cx, TraceArray<ArrayT>, array);
|
||||||
|
+ JS_RemoveExtraGCRootsTracer(cx, TraceArray<ArrayT>, array.get());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+template <class ArrayT>
|
||||||
|
+static void TestShrink(JSContext* cx) {
|
||||||
|
+ JS_GC(cx);
|
||||||
|
+
|
||||||
|
+ auto array = MakeUnique<ArrayT>();
|
||||||
|
+ ASSERT_TRUE(array != nullptr);
|
||||||
|
+
|
||||||
|
+ JS_AddExtraGCRootsTracer(cx, TraceArray<ArrayT>, array.get());
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create the array and fill it with new JS objects. With GGC these will be
|
||||||
|
+ * allocated in the nursery.
|
||||||
|
+ */
|
||||||
|
+ RootedValue value(cx);
|
||||||
|
+ const char* property = "foo";
|
||||||
|
+ for (size_t i = 0; i < ElementCount; ++i) {
|
||||||
|
+ RootedObject obj(cx, JS_NewPlainObject(cx));
|
||||||
|
+ ASSERT_FALSE(JS::ObjectIsTenured(obj));
|
||||||
|
+ value = Int32Value(i);
|
||||||
|
+ ASSERT_TRUE(JS_SetProperty(cx, obj, property, value));
|
||||||
|
+ ASSERT_TRUE(array->AppendElement(obj, fallible));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Shrink and compact the array */
|
||||||
|
+ array->RemoveElementsAt(InitialElements, ElementCount - InitialElements);
|
||||||
|
+ array->Compact();
|
||||||
|
+
|
||||||
|
+ JS_GC(cx);
|
||||||
|
+
|
||||||
|
+ ASSERT_EQ(array->Length(), InitialElements);
|
||||||
|
+ for (size_t i = 0; i < array->Length(); i++) {
|
||||||
|
+ RootedObject obj(cx, array->ElementAt(i));
|
||||||
|
+ ASSERT_TRUE(JS::ObjectIsTenured(obj));
|
||||||
|
+ ASSERT_TRUE(JS_GetProperty(cx, obj, property, &value));
|
||||||
|
+ ASSERT_TRUE(value.isInt32());
|
||||||
|
+ ASSERT_EQ(static_cast<int32_t>(i), value.toInt32());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ JS_RemoveExtraGCRootsTracer(cx, TraceArray<ArrayT>, array.get());
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+template <class ArrayT>
|
||||||
|
+static void TestArrayType(JSContext* cx) {
|
||||||
|
+ TestGrow<ArrayT>(cx);
|
||||||
|
+ TestShrink<ArrayT>(cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateGlobalAndRunTest(JSContext* cx) {
|
||||||
|
@@ -89,25 +141,11 @@
|
||||||
|
|
||||||
|
JS::Realm* oldRealm = JS::EnterRealm(cx, global);
|
||||||
|
|
||||||
|
- typedef Heap<JSObject*> ElementT;
|
||||||
|
-
|
||||||
|
- {
|
||||||
|
- nsTArray<ElementT>* array = new nsTArray<ElementT>(InitialElements);
|
||||||
|
- RunTest(cx, array);
|
||||||
|
- delete array;
|
||||||
|
- }
|
||||||
|
+ using ElementT = Heap<JSObject*>;
|
||||||
|
|
||||||
|
- {
|
||||||
|
- FallibleTArray<ElementT>* array =
|
||||||
|
- new FallibleTArray<ElementT>(InitialElements);
|
||||||
|
- RunTest(cx, array);
|
||||||
|
- delete array;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- {
|
||||||
|
- AutoTArray<ElementT, InitialElements> array;
|
||||||
|
- RunTest(cx, &array);
|
||||||
|
- }
|
||||||
|
+ TestArrayType<nsTArray<ElementT>>(cx);
|
||||||
|
+ TestArrayType<FallibleTArray<ElementT>>(cx);
|
||||||
|
+ TestArrayType<AutoTArray<ElementT, 1>>(cx);
|
||||||
|
|
||||||
|
JS::LeaveRealm(cx, oldRealm);
|
||||||
|
}
|
||||||
58
CVE-2020-26961-1.patch
Normal file
58
CVE-2020-26961-1.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Valentin Gosu <valentin.gosu@gmail.com>
|
||||||
|
# Date 1604497734 0
|
||||||
|
# Wed Nov 04 13:48:54 2020 +0000
|
||||||
|
# Node ID 179e399ac08119ef3da61766c73f265679a6cf51
|
||||||
|
# Parent 6810172b5a5861dbf847848d0a34f13787c1a6ba
|
||||||
|
Bug 1672528 - Check IPv4-mapped IPv6 addresses for being local r=dragana,necko-reviewers
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D95414
|
||||||
|
|
||||||
|
diff -r 6810172b5a58 -r 179e399ac081 netwerk/dns/DNS.cpp
|
||||||
|
--- a/netwerk/dns/DNS.cpp Wed Nov 04 17:16:26 2020 +0000
|
||||||
|
+++ b/netwerk/dns/DNS.cpp Wed Nov 04 13:48:54 2020 +0000
|
||||||
|
@@ -183,27 +183,37 @@ bool IsIPAddrV4Mapped(const NetAddr* add
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool isLocalIPv4(uint32_t networkEndianIP) {
|
||||||
|
+ uint32_t addr32 = ntohl(networkEndianIP);
|
||||||
|
+ if (addr32 >> 24 == 0x0A || // 10/8 prefix (RFC 1918).
|
||||||
|
+ addr32 >> 20 == 0xAC1 || // 172.16/12 prefix (RFC 1918).
|
||||||
|
+ addr32 >> 16 == 0xC0A8 || // 192.168/16 prefix (RFC 1918).
|
||||||
|
+ addr32 >> 16 == 0xA9FE) { // 169.254/16 prefix (Link Local).
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool IsIPAddrLocal(const NetAddr* addr) {
|
||||||
|
MOZ_ASSERT(addr);
|
||||||
|
|
||||||
|
// IPv4 RFC1918 and Link Local Addresses.
|
||||||
|
if (addr->raw.family == AF_INET) {
|
||||||
|
- uint32_t addr32 = ntohl(addr->inet.ip);
|
||||||
|
- if (addr32 >> 24 == 0x0A || // 10/8 prefix (RFC 1918).
|
||||||
|
- addr32 >> 20 == 0xAC1 || // 172.16/12 prefix (RFC 1918).
|
||||||
|
- addr32 >> 16 == 0xC0A8 || // 192.168/16 prefix (RFC 1918).
|
||||||
|
- addr32 >> 16 == 0xA9FE) { // 169.254/16 prefix (Link Local).
|
||||||
|
- return true;
|
||||||
|
- }
|
||||||
|
+ return isLocalIPv4(addr->inet.ip);
|
||||||
|
}
|
||||||
|
// IPv6 Unique and Link Local Addresses.
|
||||||
|
+ // or mapped IPv4 address
|
||||||
|
if (addr->raw.family == AF_INET6) {
|
||||||
|
uint16_t addr16 = ntohs(addr->inet6.ip.u16[0]);
|
||||||
|
if (addr16 >> 9 == 0xfc >> 1 || // fc00::/7 Unique Local Address.
|
||||||
|
addr16 >> 6 == 0xfe80 >> 6) { // fe80::/10 Link Local Address.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
+ if (IPv6ADDR_IS_V4MAPPED(&addr->inet6.ip)) {
|
||||||
|
+ return isLocalIPv4(IPv6ADDR_V4MAPPED_TO_IPADDR(&addr->inet6.ip));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
// Not an IPv4/6 local address.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
47
CVE-2020-26961-2.patch
Normal file
47
CVE-2020-26961-2.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Valentin Gosu <valentin.gosu@gmail.com>
|
||||||
|
# Date 1604497736 0
|
||||||
|
# Wed Nov 04 13:48:56 2020 +0000
|
||||||
|
# Node ID b18b9e52050cb671b57c011daa4a173fe46aec5a
|
||||||
|
# Parent 179e399ac08119ef3da61766c73f265679a6cf51
|
||||||
|
Bug 1672528 - Test r=necko-reviewers,dragana
|
||||||
|
|
||||||
|
Depends on D95414
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D95415
|
||||||
|
|
||||||
|
diff -r 179e399ac081 -r b18b9e52050c netwerk/test/unit/test_trr.js
|
||||||
|
--- a/netwerk/test/unit/test_trr.js Wed Nov 04 13:48:54 2020 +0000
|
||||||
|
+++ b/netwerk/test/unit/test_trr.js Wed Nov 04 13:48:56 2020 +0000
|
||||||
|
@@ -556,6 +556,19 @@
|
||||||
|
!Components.isSuccessCode(inStatus),
|
||||||
|
`${inStatus} should be an error code`
|
||||||
|
);
|
||||||
|
+ Services.prefs.setCharPref(
|
||||||
|
+ "network.trr.uri",
|
||||||
|
+ `https://foo.example.com:${h2Port}/doh?responseIP=::ffff:192.168.0.1`
|
||||||
|
+ );
|
||||||
|
+ [, , inStatus] = await new DNSListener(
|
||||||
|
+ "rfc1918-ipv6.example.com",
|
||||||
|
+ undefined,
|
||||||
|
+ false
|
||||||
|
+ );
|
||||||
|
+ Assert.ok(
|
||||||
|
+ !Components.isSuccessCode(inStatus),
|
||||||
|
+ `${inStatus} should be an error code`
|
||||||
|
+ );
|
||||||
|
});
|
||||||
|
|
||||||
|
// verify RFC1918 address from the server is fine when told so
|
||||||
|
@@ -568,6 +581,11 @@
|
||||||
|
);
|
||||||
|
Services.prefs.setBoolPref("network.trr.allow-rfc1918", true);
|
||||||
|
await new DNSListener("rfc1918.example.com", "192.168.0.1");
|
||||||
|
+ Services.prefs.setCharPref(
|
||||||
|
+ "network.trr.uri",
|
||||||
|
+ `https://foo.example.com:${h2Port}/doh?responseIP=::ffff:192.168.0.1`
|
||||||
|
+ );
|
||||||
|
+ await new DNSListener("rfc1918-ipv6.example.com", "::ffff:192.168.0.1");
|
||||||
|
});
|
||||||
|
|
||||||
|
// use GET and disable ECS (makes a larger request)
|
||||||
371
CVE-2020-26963-1.patch
Normal file
371
CVE-2020-26963-1.patch
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User pbz <pbz@mozilla.com>
|
||||||
|
# Date 1600689290 0
|
||||||
|
# Mon Sep 21 11:54:50 2020 +0000
|
||||||
|
# Node ID efcefed227f304781326e7c8a52633559a79b6adlist oniguruma.spec
|
||||||
|
# Parent 32d03662a363850006f648c22e825b3e886b29bc
|
||||||
|
Bug 1314912 - Rate limit calls to History and Location interfaces. r=smaug9.0-3
|
||||||
|
|
||||||
|
This adds a rate limit to methods and setters of the History and Location
|
||||||
|
for non-system callers.
|
||||||
|
The rate limit is counted per BrowsingContext and can be controlled by prefs.
|
||||||
|
|
||||||
|
This patch is based on the original rate limit patch by :freesamael.
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D90136
|
||||||
|
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 docshell/base/BrowsingContext.cpp
|
||||||
|
--- a/docshell/base/BrowsingContext.cpp 2020-07-21 06:49:37.000000000 +0800
|
||||||
|
+++ b/docshell/base/BrowsingContext.cpp 2021-01-06 10:22:57.966851379 +0800
|
||||||
|
@@ -2459,6 +2459,56 @@ bool BrowsingContext::CanSet(FieldIndex<
|
||||||
|
return GetBrowserId() == 0 && IsTop() && Children().IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
+nsresult BrowsingContext::CheckLocationChangeRateLimit(CallerType aCallerType) {
|
||||||
|
+ // We only rate limit non system callers
|
||||||
|
+ if (aCallerType == CallerType::System) {
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Fetch rate limiting preferences
|
||||||
|
+ uint32_t limitCount =
|
||||||
|
+ StaticPrefs::dom_navigation_locationChangeRateLimit_count();
|
||||||
|
+ uint32_t timeSpanSeconds =
|
||||||
|
+ StaticPrefs::dom_navigation_locationChangeRateLimit_timespan();
|
||||||
|
+
|
||||||
|
+ // Disable throttling if either of the preferences is set to 0.
|
||||||
|
+ if (limitCount == 0 || timeSpanSeconds == 0) {
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TimeDuration throttleSpan = TimeDuration::FromSeconds(timeSpanSeconds);
|
||||||
|
+
|
||||||
|
+ if (mLocationChangeRateLimitSpanStart.IsNull() ||
|
||||||
|
+ ((TimeStamp::Now() - mLocationChangeRateLimitSpanStart) > throttleSpan)) {
|
||||||
|
+ // Initial call or timespan exceeded, reset counter and timespan.
|
||||||
|
+ mLocationChangeRateLimitSpanStart = TimeStamp::Now();
|
||||||
|
+ mLocationChangeRateLimitCount = 1;
|
||||||
|
+ return NS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (mLocationChangeRateLimitCount >= limitCount) {
|
||||||
|
+ // Rate limit reached
|
||||||
|
+
|
||||||
|
+ Document* doc = GetDocument();
|
||||||
|
+ if (doc) {
|
||||||
|
+ nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,NS_LITERAL_CSTRING("DOM"), doc,
|
||||||
|
+ nsContentUtils::eDOM_PROPERTIES,
|
||||||
|
+ "LocChangeFloodingPrevented");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mLocationChangeRateLimitCount++;
|
||||||
|
+ return NS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void BrowsingContext::ResetLocationChangeRateLimit() {
|
||||||
|
+ // Resetting the timestamp object will cause the check function to
|
||||||
|
+ // init again and reset the rate limit.
|
||||||
|
+ mLocationChangeRateLimitSpanStart = TimeStamp();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
} // namespace dom
|
||||||
|
|
||||||
|
namespace ipc {
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 docshell/base/BrowsingContext.h
|
||||||
|
--- a/docshell/base/BrowsingContext.h 2020-07-21 06:49:37.000000000 +0800
|
||||||
|
+++ b/docshell/base/BrowsingContext.h 2021-01-06 10:22:57.954851198 +0800
|
||||||
|
@@ -652,6 +652,16 @@ class BrowsingContext : public nsILoadCo
|
||||||
|
|
||||||
|
bool CrossOriginIsolated();
|
||||||
|
|
||||||
|
+ // Checks if we reached the rate limit for calls to Location and History API.
|
||||||
|
+ // The rate limit is controlled by the
|
||||||
|
+ // "dom.navigation.locationChangeRateLimit" prefs.
|
||||||
|
+ // Rate limit applies per BrowsingContext.
|
||||||
|
+ // Returns NS_OK if we are below the rate limit and increments the counter.
|
||||||
|
+ // Returns NS_ERROR_DOM_SECURITY_ERR if limit is reached.
|
||||||
|
+ nsresult CheckLocationChangeRateLimit(CallerType aCallerType);
|
||||||
|
+
|
||||||
|
+ void ResetLocationChangeRateLimit();
|
||||||
|
+
|
||||||
|
protected:
|
||||||
|
virtual ~BrowsingContext();
|
||||||
|
BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup,
|
||||||
|
@@ -932,6 +942,11 @@ class BrowsingContext : public nsILoadCo
|
||||||
|
|
||||||
|
RefPtr<SessionStorageManager> mSessionStorageManager;
|
||||||
|
RefPtr<ChildSHistory> mChildSessionHistory;
|
||||||
|
+
|
||||||
|
+ // Counter and time span for rate limiting Location and History API calls.
|
||||||
|
+ // Used by CheckLocationChangeRateLimit. Do not apply cross-process.
|
||||||
|
+ uint32_t mLocationChangeRateLimitCount;
|
||||||
|
+ mozilla::TimeStamp mLocationChangeRateLimitSpanStart;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 docshell/shistory/ChildSHistory.cpp
|
||||||
|
--- a/docshell/shistory/ChildSHistory.cpp 2020-07-21 06:49:37.000000000 +0800
|
||||||
|
+++ b/docshell/shistory/ChildSHistory.cpp 2021-01-06 10:22:58.058852764 +0800
|
||||||
|
@@ -105,7 +105,14 @@ void ChildSHistory::Go(int32_t aOffset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-void ChildSHistory::AsyncGo(int32_t aOffset, bool aRequireUserInteraction) {
|
||||||
|
+void ChildSHistory::AsyncGo(int32_t aOffset, bool aRequireUserInteraction,
|
||||||
|
+ CallerType aCallerType, ErrorResult& aRv) {
|
||||||
|
+ nsresult rv = mBrowsingContext->CheckLocationChangeRateLimit(aCallerType);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ aRv.Throw(rv);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!CanGo(aOffset)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 docshell/shistory/ChildSHistory.h
|
||||||
|
--- a/docshell/shistory/ChildSHistory.h 2020-07-21 06:49:37.000000000 +0800
|
||||||
|
+++ b/docshell/shistory/ChildSHistory.h 2021-01-06 10:22:58.058852764 +0800
|
||||||
|
@@ -64,8 +64,8 @@ class ChildSHistory : public nsISupports
|
||||||
|
*/
|
||||||
|
bool CanGo(int32_t aOffset);
|
||||||
|
void Go(int32_t aOffset, bool aRequireUserInteraction, ErrorResult& aRv);
|
||||||
|
- void AsyncGo(int32_t aOffset, bool aRequireUserInteraction);
|
||||||
|
-
|
||||||
|
+ void AsyncGo(int32_t aOffset, bool aRequireUserInteraction,
|
||||||
|
+ CallerType aCallerType, ErrorResult& aRv);
|
||||||
|
void RemovePendingHistoryNavigations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 dom/base/LocationBase.cpp
|
||||||
|
--- a/dom/base/LocationBase.cpp 2020-07-21 04:53:13.000000000 +0800
|
||||||
|
+++ b/dom/base/LocationBase.cpp 2021-01-06 10:22:46.030671698 +0800
|
||||||
|
@@ -116,6 +116,16 @@ void LocationBase::SetURI(nsIURI* aURI,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ CallerType callerType = aSubjectPrincipal.IsSystemPrincipal()
|
||||||
|
+ ? CallerType::System
|
||||||
|
+ : CallerType::NonSystem;
|
||||||
|
+
|
||||||
|
+ nsresult rv = bc->CheckLocationChangeRateLimit(callerType);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ aRv.Throw(rv);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
RefPtr<nsDocShellLoadState> loadState =
|
||||||
|
CheckURL(aURI, aSubjectPrincipal, aRv);
|
||||||
|
if (aRv.Failed()) {
|
||||||
|
@@ -141,7 +151,7 @@ void LocationBase::SetURI(nsIURI* aURI,
|
||||||
|
loadState->SetLoadFlags(nsIWebNavigation::LOAD_FLAGS_NONE);
|
||||||
|
loadState->SetFirstParty(true);
|
||||||
|
|
||||||
|
- nsresult rv = bc->LoadURI(loadState);
|
||||||
|
+ rv = bc->LoadURI(loadState);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
aRv.Throw(rv);
|
||||||
|
}
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 dom/base/nsHistory.cpp
|
||||||
|
--- a/dom/base/nsHistory.cpp 2020-07-21 06:49:37.000000000 +0800
|
||||||
|
+++ b/dom/base/nsHistory.cpp 2021-01-06 10:22:46.030671698 +0800
|
||||||
|
@@ -135,7 +135,7 @@ void nsHistory::GetState(JSContext* aCx,
|
||||||
|
aResult.setNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
-void nsHistory::Go(int32_t aDelta, ErrorResult& aRv) {
|
||||||
|
+void nsHistory::Go(int32_t aDelta, CallerType aCallerType, ErrorResult& aRv) {
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
|
||||||
|
if (!win || !win->HasActiveDocument()) {
|
||||||
|
return aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||||
|
@@ -157,15 +157,17 @@ void nsHistory::Go(int32_t aDelta, Error
|
||||||
|
|
||||||
|
// Ignore the return value from Go(), since returning errors from Go() can
|
||||||
|
// lead to exceptions and a possible leak of history length
|
||||||
|
+ // AsyncGo throws if we hit the location change rate limit.
|
||||||
|
if (StaticPrefs::dom_window_history_async()) {
|
||||||
|
- session_history->AsyncGo(aDelta, /* aRequireUserInteraction = */ false);
|
||||||
|
+ session_history->AsyncGo(aDelta, /* aRequireUserInteraction = */ false,
|
||||||
|
+ aCallerType, aRv);
|
||||||
|
} else {
|
||||||
|
session_history->Go(aDelta, /* aRequireUserInteraction = */ false,
|
||||||
|
IgnoreErrors());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-void nsHistory::Back(ErrorResult& aRv) {
|
||||||
|
+void nsHistory::Back(CallerType aCallerType, ErrorResult& aRv) {
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
|
||||||
|
if (!win || !win->HasActiveDocument()) {
|
||||||
|
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||||
|
@@ -181,13 +183,14 @@ void nsHistory::Back(ErrorResult& aRv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StaticPrefs::dom_window_history_async()) {
|
||||||
|
- sHistory->AsyncGo(-1, /* aRequireUserInteraction = */ false);
|
||||||
|
+ sHistory->AsyncGo(-1, /* aRequireUserInteraction = */ false, aCallerType,
|
||||||
|
+ aRv);
|
||||||
|
} else {
|
||||||
|
sHistory->Go(-1, /* aRequireUserInteraction = */ false, IgnoreErrors());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-void nsHistory::Forward(ErrorResult& aRv) {
|
||||||
|
+void nsHistory::Forward(CallerType aCallerType, ErrorResult& aRv) {
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
|
||||||
|
if (!win || !win->HasActiveDocument()) {
|
||||||
|
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||||
|
@@ -203,7 +206,8 @@ void nsHistory::Forward(ErrorResult& aRv
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StaticPrefs::dom_window_history_async()) {
|
||||||
|
- sHistory->AsyncGo(1, /* aRequireUserInteraction = */ false);
|
||||||
|
+ sHistory->AsyncGo(1, /* aRequireUserInteraction = */ false, aCallerType,
|
||||||
|
+ aRv);
|
||||||
|
} else {
|
||||||
|
sHistory->Go(1, /* aRequireUserInteraction = */ false, IgnoreErrors());
|
||||||
|
}
|
||||||
|
@@ -211,19 +215,20 @@ void nsHistory::Forward(ErrorResult& aRv
|
||||||
|
|
||||||
|
void nsHistory::PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
|
||||||
|
const nsAString& aTitle, const nsAString& aUrl,
|
||||||
|
- ErrorResult& aRv) {
|
||||||
|
- PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, false);
|
||||||
|
+ CallerType aCallerType, ErrorResult& aRv) {
|
||||||
|
+ PushOrReplaceState(aCx, aData, aTitle, aUrl, aCallerType, aRv, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsHistory::ReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
|
||||||
|
const nsAString& aTitle, const nsAString& aUrl,
|
||||||
|
- ErrorResult& aRv) {
|
||||||
|
- PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, true);
|
||||||
|
+ CallerType aCallerType, ErrorResult& aRv) {
|
||||||
|
+ PushOrReplaceState(aCx, aData, aTitle, aUrl, aCallerType, aRv, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsHistory::PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
- const nsAString& aUrl, ErrorResult& aRv,
|
||||||
|
+ const nsAString& aUrl,
|
||||||
|
+ CallerType aCallerType, ErrorResult& aRv,
|
||||||
|
bool aReplace) {
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> win(do_QueryReferent(mInnerWindow));
|
||||||
|
if (!win) {
|
||||||
|
@@ -238,6 +243,15 @@ void nsHistory::PushOrReplaceState(JSCon
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ BrowsingContext* bc = win->GetBrowsingContext();
|
||||||
|
+ if (bc) {
|
||||||
|
+ nsresult rv = bc->CheckLocationChangeRateLimit(aCallerType);
|
||||||
|
+ if (NS_FAILED(rv)) {
|
||||||
|
+ aRv.Throw(rv);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// AddState might run scripts, so we need to hold a strong reference to the
|
||||||
|
// docShell here to keep it from going away.
|
||||||
|
nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 dom/base/nsHistory.h
|
||||||
|
--- a/dom/base/nsHistory.h 2020-07-21 04:53:13.000000000 +0800
|
||||||
|
+++ b/dom/base/nsHistory.h 2021-01-06 10:22:46.030671698 +0800
|
||||||
|
@@ -42,14 +42,17 @@ class nsHistory final : public nsISuppor
|
||||||
|
mozilla::ErrorResult& aRv);
|
||||||
|
void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||||
|
mozilla::ErrorResult& aRv) const;
|
||||||
|
- void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
|
||||||
|
- void Back(mozilla::ErrorResult& aRv);
|
||||||
|
- void Forward(mozilla::ErrorResult& aRv);
|
||||||
|
+ void Go(int32_t aDelta, mozilla::dom::CallerType aCallerType,
|
||||||
|
+ mozilla::ErrorResult& aRv);
|
||||||
|
+ void Back(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aRv);
|
||||||
|
+ void Forward(mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aRv);
|
||||||
|
void PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
|
||||||
|
const nsAString& aTitle, const nsAString& aUrl,
|
||||||
|
+ mozilla::dom::CallerType aCallerType,
|
||||||
|
mozilla::ErrorResult& aRv);
|
||||||
|
void ReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
|
||||||
|
const nsAString& aTitle, const nsAString& aUrl,
|
||||||
|
+ mozilla::dom::CallerType aCallerType,
|
||||||
|
mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
@@ -59,6 +62,7 @@ class nsHistory final : public nsISuppor
|
||||||
|
|
||||||
|
void PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
|
||||||
|
const nsAString& aTitle, const nsAString& aUrl,
|
||||||
|
+ mozilla::dom::CallerType aCallerType,
|
||||||
|
mozilla::ErrorResult& aRv, bool aReplace);
|
||||||
|
|
||||||
|
already_AddRefed<mozilla::dom::ChildSHistory> GetSessionHistory() const;
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 dom/chrome-webidl/BrowsingContext.webidl
|
||||||
|
--- a/dom/chrome-webidl/BrowsingContext.webidl 2020-07-21 06:49:37.000000000 +0800
|
||||||
|
+++ b/dom/chrome-webidl/BrowsingContext.webidl 2021-01-06 10:22:42.362616481 +0800
|
||||||
|
@@ -120,6 +120,9 @@ interface BrowsingContext {
|
||||||
|
* under the new browser element.
|
||||||
|
*/
|
||||||
|
attribute unsigned long long browserId;
|
||||||
|
+
|
||||||
|
+ // Resets the location change rate limit. Used for testing.
|
||||||
|
+ void resetLocationChangeRateLimit();
|
||||||
|
};
|
||||||
|
|
||||||
|
BrowsingContext includes LoadContextMixin;
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 dom/locales/en-US/chrome/dom/dom.properties
|
||||||
|
--- a/dom/locales/en-US/chrome/dom/dom.properties 2020-07-21 06:49:37.000000000 +0800
|
||||||
|
+++ b/dom/locales/en-US/chrome/dom/dom.properties 2021-01-06 10:22:42.418617324 +0800
|
||||||
|
@@ -393,3 +393,5 @@ UnknownProtocolNavigationPrevented=Preve
|
||||||
|
PostMessageSharedMemoryObjectToCrossOriginWarning=Cannot post message containing a shared memory object to a cross-origin window.
|
||||||
|
# LOCALIZATION NOTE: %S is the URL of the resource in question
|
||||||
|
UnusedLinkPreloadPending=The resource at “%S” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly.
|
||||||
|
+# LOCALIZATION NOTE: Do not translate "Location" and "History".
|
||||||
|
+LocChangeFloodingPrevented=Too many calls to Location or History APIs within a short timeframe.
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 dom/webidl/History.webidl
|
||||||
|
--- a/dom/webidl/History.webidl 2020-07-21 04:53:19.000000000 +0800
|
||||||
|
+++ b/dom/webidl/History.webidl 2021-01-06 10:22:42.298615518 +0800
|
||||||
|
@@ -21,14 +21,14 @@ interface History {
|
||||||
|
attribute ScrollRestoration scrollRestoration;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute any state;
|
||||||
|
- [Throws]
|
||||||
|
+ [Throws, NeedsCallerType]
|
||||||
|
void go(optional long delta = 0);
|
||||||
|
- [Throws]
|
||||||
|
+ [Throws, NeedsCallerType]
|
||||||
|
void back();
|
||||||
|
- [Throws]
|
||||||
|
+ [Throws, NeedsCallerType]
|
||||||
|
void forward();
|
||||||
|
- [Throws]
|
||||||
|
+ [Throws, NeedsCallerType]
|
||||||
|
void pushState(any data, DOMString title, optional DOMString? url = null);
|
||||||
|
- [Throws]
|
||||||
|
+ [Throws, NeedsCallerType]
|
||||||
|
void replaceState(any data, DOMString title, optional DOMString? url = null);
|
||||||
|
};
|
||||||
|
diff -r 32d03662a363 -r efcefed227f3 modules/libpref/init/StaticPrefList.yaml
|
||||||
|
--- a/modules/libpref/init/StaticPrefList.yaml 2021-01-06 10:25:09.272827991 +0800
|
||||||
|
+++ b/modules/libpref/init/StaticPrefList.yaml 2021-01-06 10:22:36.458527604 +0800
|
||||||
|
@@ -2181,6 +2181,19 @@
|
||||||
|
value: true
|
||||||
|
mirror: always
|
||||||
|
|
||||||
|
+# Limit of location change caused by content scripts in a time span per
|
||||||
|
+# BrowsingContext. This includes calls to History and Location APIs.
|
||||||
|
+- name: dom.navigation.locationChangeRateLimit.count
|
||||||
|
+ type: uint32_t
|
||||||
|
+ value: 200
|
||||||
|
+ mirror: always
|
||||||
|
+
|
||||||
|
+# Time span in seconds for location change rate limit.
|
||||||
|
+- name: dom.navigation.locationChangeRateLimit.timespan
|
||||||
|
+ type: uint32_t
|
||||||
|
+ value: 10
|
||||||
|
+ mirror: always
|
||||||
|
+
|
||||||
|
# Network Information API
|
||||||
|
- name: dom.netinfo.enabled
|
||||||
|
type: RelaxedAtomicBool
|
||||||
118
CVE-2020-26963-2.patch
Normal file
118
CVE-2020-26963-2.patch
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User pbz <pbz@mozilla.com>
|
||||||
|
# Date 1600689297 0
|
||||||
|
# Mon Sep 21 11:54:57 2020 +0000
|
||||||
|
# Node ID ff5164e4aec8cd7a86df0b5f97842fb1f6f765a6
|
||||||
|
# Parent efcefed227f304781326e7c8a52633559a79b6ad
|
||||||
|
Bug 1314912 - Added test for location change rate limit. r=smaug
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D90137
|
||||||
|
|
||||||
|
diff -r efcefed227f3 -r ff5164e4aec8 docshell/test/navigation/mochitest.ini
|
||||||
|
--- a/docshell/test/navigation/mochitest.ini Mon Sep 21 11:54:50 2020 +0000
|
||||||
|
+++ b/docshell/test/navigation/mochitest.ini Mon Sep 21 11:54:57 2020 +0000
|
||||||
|
@@ -97,3 +97,4 @@
|
||||||
|
[test_triggeringprincipal_parent_iframe_window_open.html]
|
||||||
|
[test_triggeringprincipal_iframe_iframe_window_open.html]
|
||||||
|
[test_contentpolicy_block_window.html]
|
||||||
|
+[test_rate_limit_location_change.html]
|
||||||
|
diff -r efcefed227f3 -r ff5164e4aec8 docshell/test/navigation/test_rate_limit_location_change.html
|
||||||
|
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||||
|
+++ b/docshell/test/navigation/test_rate_limit_location_change.html Mon Sep 21 11:54:57 2020 +0000
|
||||||
|
@@ -0,0 +1,96 @@
|
||||||
|
+<!DOCTYPE HTML>
|
||||||
|
+<html>
|
||||||
|
+<!--
|
||||||
|
+https://bugzilla.mozilla.org/show_bug.cgi?id=1314912
|
||||||
|
+-->
|
||||||
|
+<head>
|
||||||
|
+ <meta charset="utf-8">
|
||||||
|
+ <title>Test for Bug 1314912</title>
|
||||||
|
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
+ <script type="application/javascript">
|
||||||
|
+
|
||||||
|
+ /** Test for Bug 1314912 **/
|
||||||
|
+
|
||||||
|
+ const RATE_LIMIT_COUNT = 90;
|
||||||
|
+ const RATE_LIMIT_TIME_SPAN = 3;
|
||||||
|
+
|
||||||
|
+ async function setup() {
|
||||||
|
+ await SpecialPowers.pushPrefEnv({set: [
|
||||||
|
+ ["dom.navigation.locationChangeRateLimit.count", RATE_LIMIT_COUNT],
|
||||||
|
+ ["dom.navigation.locationChangeRateLimit.timespan", RATE_LIMIT_TIME_SPAN]]});
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ let inc = 0;
|
||||||
|
+
|
||||||
|
+ const rateLimitedFunctions = (win) => ({
|
||||||
|
+ "history.replaceState": () => win.history.replaceState(null, "test", `${win.location.href}#${inc++}`),
|
||||||
|
+ "history.pushState": () => win.history.pushState(null, "test", `${win.location.href}#${inc++}`),
|
||||||
|
+ "history.back": () => win.history.back(),
|
||||||
|
+ "history.forward": () => win.history.forward(),
|
||||||
|
+ "history.go": () => win.history.go(-1),
|
||||||
|
+ "location.hash": () => win.location.hash = inc++,
|
||||||
|
+ "location.host": () => win.location.host = win.location.host + "",
|
||||||
|
+ "location.hostname": () => win.location.hostname = win.location.hostname + "",
|
||||||
|
+ "location.pathname": () => win.location.pathname = win.location.pathname + "",
|
||||||
|
+ "location.port": () => win.location.port = win.location.port + "",
|
||||||
|
+ "location.protocol": () => win.location.protocol = win.location.protocol + "",
|
||||||
|
+ "location.search": () => win.location.search = win.location.search + "",
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ async function test() {
|
||||||
|
+ await setup();
|
||||||
|
+
|
||||||
|
+ // Open new window and wait for it to load
|
||||||
|
+ let win = window.open("blank.html");
|
||||||
|
+ await new Promise((resolve) => SimpleTest.waitForFocus(resolve, win))
|
||||||
|
+
|
||||||
|
+ // Execute the history and location functions
|
||||||
|
+ Object.entries(rateLimitedFunctions(win)).forEach(([name, fn]) => {
|
||||||
|
+ // Reset the rate limit for the next run.
|
||||||
|
+ info("Reset rate limit.");
|
||||||
|
+ SpecialPowers.wrap(win).browsingContext.resetLocationChangeRateLimit();
|
||||||
|
+
|
||||||
|
+ info(`Calling ${name} ${RATE_LIMIT_COUNT} times to reach the rate limit.`);
|
||||||
|
+ for(let i = 0; i< RATE_LIMIT_COUNT; i++) {
|
||||||
|
+ fn.call(this);
|
||||||
|
+ }
|
||||||
|
+ // Next calls should throw because we're above the rate limit
|
||||||
|
+ for(let i = 0; i < 5; i++) {
|
||||||
|
+ SimpleTest.doesThrow(() => fn.call(this), `Call #${RATE_LIMIT_COUNT + i + 1} to ${name} should throw.`);
|
||||||
|
+ }
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+ // We didn't reset the rate limit after the last loop iteration above.
|
||||||
|
+ // Wait for the rate limit timer to expire.
|
||||||
|
+ SimpleTest.requestFlakyTimeout("Waiting to trigger rate limit reset.");
|
||||||
|
+ await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||||
|
+
|
||||||
|
+ // Calls should be allowed again.
|
||||||
|
+ Object.entries(rateLimitedFunctions(win)).forEach(([name, fn]) => {
|
||||||
|
+ let didThrow = false;
|
||||||
|
+ try {
|
||||||
|
+ fn.call(this);
|
||||||
|
+ } catch(error) {
|
||||||
|
+ didThrow = true;
|
||||||
|
+ }
|
||||||
|
+ is(didThrow, false, `Call to ${name} must not throw.`)
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ // Cleanup
|
||||||
|
+ win.close();
|
||||||
|
+ SpecialPowers.wrap(win).browsingContext.resetLocationChangeRateLimit();
|
||||||
|
+ SimpleTest.finish();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ </script>
|
||||||
|
+</head>
|
||||||
|
+<body onload="setTimeout(test, 0);">
|
||||||
|
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1314912">Mozilla Bug 1314912</a>
|
||||||
|
+<p id="display"></p>
|
||||||
|
+<div id="content" style="display: none">
|
||||||
|
+</div>
|
||||||
|
+<pre id="test">
|
||||||
|
+</pre>
|
||||||
|
+</body>
|
||||||
|
+</html>
|
||||||
28
CVE-2020-26965.patch
Normal file
28
CVE-2020-26965.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Makoto Kato <m_kato@ga2.so-net.ne.jp>
|
||||||
|
# Date 1601537039 0
|
||||||
|
# Thu Oct 01 07:23:59 2020 +0000
|
||||||
|
# Node ID 3b746525d6472490b44e55e4766078372e0380c3
|
||||||
|
# Parent e6b1234900b328782dd4f93b34222bf49b470ac2
|
||||||
|
Bug 1661617 - Use password hint for software keyboard. r=masayuki
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D91237
|
||||||
|
|
||||||
|
diff -r e6b1234900b3 -r 3b746525d647 dom/events/IMEStateManager.cpp
|
||||||
|
--- a/dom/events/IMEStateManager.cpp Thu Oct 08 05:39:33 2020 +0000
|
||||||
|
+++ b/dom/events/IMEStateManager.cpp Thu Oct 01 07:23:59 2020 +0000
|
||||||
|
@@ -1260,7 +1260,13 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aContent->IsHTMLElement(nsGkAtoms::input)) {
|
||||||
|
- HTMLInputElement::FromNode(aContent)->GetType(context.mHTMLInputType);
|
||||||
|
+ HTMLInputElement* inputElement = HTMLInputElement::FromNode(aContent);
|
||||||
|
+ if (inputElement->HasBeenTypePassword() && aState.IsEditable()) {
|
||||||
|
+ context.mHTMLInputType.AssignLiteral("password");
|
||||||
|
+ } else {
|
||||||
|
+ inputElement->GetType(context.mHTMLInputType);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
GetActionHint(*aContent, context.mActionHint);
|
||||||
|
} else if (aContent->IsHTMLElement(nsGkAtoms::textarea)) {
|
||||||
|
context.mHTMLInputType.Assign(nsGkAtoms::textarea->GetUTF16String());
|
||||||
312
CVE-2020-26966.patch
Normal file
312
CVE-2020-26966.patch
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Valentin Gosu <valentin.gosu@gmail.com>
|
||||||
|
# Date 1604045785 0
|
||||||
|
# Fri Oct 30 08:16:25 2020 +0000
|
||||||
|
# Node ID 0344d5a76b7db85d4f6d5f5f34649b9111eb6094
|
||||||
|
# Parent 3e57839bffd2ea7c3b53a9f7ccd75fd308afd801
|
||||||
|
Bug 1663571 - Resolve single label DNS queries using DnsQuery_A r=necko-reviewers,dragana
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D91117
|
||||||
|
|
||||||
|
diff -r 3e57839bffd2 -r 0344d5a76b7d modules/libpref/init/StaticPrefList.yaml
|
||||||
|
--- a/modules/libpref/init/StaticPrefList.yaml Fri Oct 30 10:19:14 2020 +0000
|
||||||
|
+++ b/modules/libpref/init/StaticPrefList.yaml Fri Oct 30 08:16:25 2020 +0000
|
||||||
|
@@ -7978,6 +7978,14 @@
|
||||||
|
value: 2000
|
||||||
|
mirror: always
|
||||||
|
|
||||||
|
+# When true on Windows DNS resolutions for single label domains
|
||||||
|
+# (domains that don't contain a dot) will be resolved using the DnsQuery
|
||||||
|
+# API instead of PR_GetAddrInfoByName
|
||||||
|
+- name: network.dns.dns_query_single_label
|
||||||
|
+ type: RelaxedAtomicBool
|
||||||
|
+ value: true
|
||||||
|
+ mirror: always
|
||||||
|
+
|
||||||
|
# Whether the SOCKS proxy should be in charge of DNS resolution.
|
||||||
|
- name: network.proxy.socks_remote_dns
|
||||||
|
type: bool
|
||||||
|
diff -r 3e57839bffd2 -r 0344d5a76b7d netwerk/dns/GetAddrInfo.cpp
|
||||||
|
--- a/netwerk/dns/GetAddrInfo.cpp Fri Oct 30 10:19:14 2020 +0000
|
||||||
|
+++ b/netwerk/dns/GetAddrInfo.cpp Fri Oct 30 08:16:25 2020 +0000
|
||||||
|
@@ -5,6 +5,18 @@
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "GetAddrInfo.h"
|
||||||
|
+
|
||||||
|
+#ifdef DNSQUERY_AVAILABLE
|
||||||
|
+// There is a bug in windns.h where the type of parameter ppQueryResultsSet for
|
||||||
|
+// DnsQuery_A is dependent on UNICODE being set. It should *always* be
|
||||||
|
+// PDNS_RECORDA, but if UNICODE is set it is PDNS_RECORDW. To get around this
|
||||||
|
+// we make sure that UNICODE is unset.
|
||||||
|
+# undef UNICODE
|
||||||
|
+# include <ws2tcpip.h>
|
||||||
|
+# undef GetAddrInfo
|
||||||
|
+# include <windns.h>
|
||||||
|
+#endif // DNSQUERY_AVAILABLE
|
||||||
|
+
|
||||||
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
|
#include "mozilla/net/DNS.h"
|
||||||
|
#include "NativeDNSResolverOverrideParent.h"
|
||||||
|
@@ -19,17 +31,6 @@
|
||||||
|
#include "mozilla/Logging.h"
|
||||||
|
#include "mozilla/StaticPrefs_network.h"
|
||||||
|
|
||||||
|
-#ifdef DNSQUERY_AVAILABLE
|
||||||
|
-// There is a bug in windns.h where the type of parameter ppQueryResultsSet for
|
||||||
|
-// DnsQuery_A is dependent on UNICODE being set. It should *always* be
|
||||||
|
-// PDNS_RECORDA, but if UNICODE is set it is PDNS_RECORDW. To get around this
|
||||||
|
-// we make sure that UNICODE is unset.
|
||||||
|
-# undef UNICODE
|
||||||
|
-# include <ws2tcpip.h>
|
||||||
|
-# undef GetAddrInfo
|
||||||
|
-# include <windns.h>
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
namespace mozilla {
|
||||||
|
namespace net {
|
||||||
|
|
||||||
|
@@ -42,6 +43,11 @@
|
||||||
|
MOZ_LOG(gGetAddrInfoLog, LogLevel::Warning, ("[DNS]: " msg, ##__VA_ARGS__))
|
||||||
|
|
||||||
|
#ifdef DNSQUERY_AVAILABLE
|
||||||
|
+
|
||||||
|
+# define COMPUTER_NAME_BUFFER_SIZE 100
|
||||||
|
+static char sDNSComputerName[COMPUTER_NAME_BUFFER_SIZE];
|
||||||
|
+static char sNETBIOSComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||||||
|
+
|
||||||
|
////////////////////////////
|
||||||
|
// WINDOWS IMPLEMENTATION //
|
||||||
|
////////////////////////////
|
||||||
|
@@ -56,45 +62,63 @@
|
||||||
|
// equal with the one already there. Gets the TTL value by calling
|
||||||
|
// to DnsQuery_A and iterating through the returned
|
||||||
|
// records to find the one with the smallest TTL value.
|
||||||
|
-static MOZ_ALWAYS_INLINE nsresult _GetMinTTLForRequestType_Windows(
|
||||||
|
- const char* aHost, uint16_t aRequestType, unsigned int* aResult) {
|
||||||
|
- MOZ_ASSERT(aHost);
|
||||||
|
- MOZ_ASSERT(aResult);
|
||||||
|
+static MOZ_ALWAYS_INLINE nsresult _CallDnsQuery_A_Windows(
|
||||||
|
+ const nsACString& aHost, uint16_t aAddressFamily, DWORD aFlags,
|
||||||
|
+ std::function<void(PDNS_RECORDA)> aCallback) {
|
||||||
|
+ NS_ConvertASCIItoUTF16 name(aHost);
|
||||||
|
+
|
||||||
|
+ auto callDnsQuery_A = [&](uint16_t reqFamily) {
|
||||||
|
+ PDNS_RECORDA dnsData = nullptr;
|
||||||
|
+ DNS_STATUS status = DnsQuery_A(aHost.BeginReading(), reqFamily, aFlags,
|
||||||
|
+ nullptr, &dnsData, nullptr);
|
||||||
|
+ if (status == DNS_INFO_NO_RECORDS || status == DNS_ERROR_RCODE_NAME_ERROR ||
|
||||||
|
+ !dnsData) {
|
||||||
|
+ LOG("No DNS records found for %s. status=%X. reqFamily = %X\n",
|
||||||
|
+ aHost.BeginReading(), status, reqFamily);
|
||||||
|
+ return NS_ERROR_FAILURE;
|
||||||
|
+ } else if (status != NOERROR) {
|
||||||
|
+ LOG_WARNING("DnsQuery_A failed with status %X.\n", status);
|
||||||
|
+ return NS_ERROR_UNEXPECTED;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- PDNS_RECORDA dnsData = nullptr;
|
||||||
|
- DNS_STATUS status = DnsQuery_A(
|
||||||
|
- aHost, aRequestType,
|
||||||
|
- (DNS_QUERY_STANDARD | DNS_QUERY_NO_NETBT | DNS_QUERY_NO_HOSTS_FILE |
|
||||||
|
- DNS_QUERY_NO_MULTICAST | DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE |
|
||||||
|
- DNS_QUERY_DONT_RESET_TTL_VALUES),
|
||||||
|
- nullptr, &dnsData, nullptr);
|
||||||
|
- if (status == DNS_INFO_NO_RECORDS || status == DNS_ERROR_RCODE_NAME_ERROR ||
|
||||||
|
- !dnsData) {
|
||||||
|
- LOG("No DNS records found for %s. status=%X. aRequestType = %X\n", aHost,
|
||||||
|
- status, aRequestType);
|
||||||
|
- return NS_ERROR_FAILURE;
|
||||||
|
- } else if (status != NOERROR) {
|
||||||
|
- LOG_WARNING("DnsQuery_A failed with status %X.\n", status);
|
||||||
|
- return NS_ERROR_UNEXPECTED;
|
||||||
|
+ for (PDNS_RECORDA curRecord = dnsData; curRecord;
|
||||||
|
+ curRecord = curRecord->pNext) {
|
||||||
|
+ // Only records in the answer section are important
|
||||||
|
+ if (curRecord->Flags.S.Section != DnsSectionAnswer) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (curRecord->wType != reqFamily) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ aCallback(curRecord);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ DnsFree(dnsData, DNS_FREE_TYPE::DnsFreeRecordList);
|
||||||
|
+ return NS_OK;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (aAddressFamily == PR_AF_UNSPEC || aAddressFamily == PR_AF_INET) {
|
||||||
|
+ callDnsQuery_A(DNS_TYPE_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (PDNS_RECORDA curRecord = dnsData; curRecord;
|
||||||
|
- curRecord = curRecord->pNext) {
|
||||||
|
- // Only records in the answer section are important
|
||||||
|
- if (curRecord->Flags.S.Section != DnsSectionAnswer) {
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
+ if (aAddressFamily == PR_AF_UNSPEC || aAddressFamily == PR_AF_INET6) {
|
||||||
|
+ callDnsQuery_A(DNS_TYPE_AAAA);
|
||||||
|
+ }
|
||||||
|
+ return NS_OK;
|
||||||
|
+}
|
||||||
|
|
||||||
|
- if (curRecord->wType == aRequestType) {
|
||||||
|
- *aResult = std::min<unsigned int>(*aResult, curRecord->dwTtl);
|
||||||
|
- } else {
|
||||||
|
- LOG("Received unexpected record type %u in response for %s.\n",
|
||||||
|
- curRecord->wType, aHost);
|
||||||
|
- }
|
||||||
|
+bool recordTypeMatchesRequest(uint16_t wType, uint16_t aAddressFamily) {
|
||||||
|
+ if (aAddressFamily == PR_AF_UNSPEC) {
|
||||||
|
+ return wType == DNS_TYPE_A || wType == DNS_TYPE_AAAA;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- DnsFree(dnsData, DNS_FREE_TYPE::DnsFreeRecordList);
|
||||||
|
- return NS_OK;
|
||||||
|
+ if (aAddressFamily == PR_AF_INET) {
|
||||||
|
+ return wType == DNS_TYPE_A;
|
||||||
|
+ }
|
||||||
|
+ if (aAddressFamily == PR_AF_INET6) {
|
||||||
|
+ return wType == DNS_TYPE_AAAA;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MOZ_ALWAYS_INLINE nsresult _GetTTLData_Windows(const nsACString& aHost,
|
||||||
|
@@ -110,13 +134,21 @@
|
||||||
|
// In order to avoid using ANY records which are not always implemented as a
|
||||||
|
// "Gimme what you have" request in hostname resolvers, we should send A
|
||||||
|
// and/or AAAA requests, based on the address family requested.
|
||||||
|
+ const DWORD ttlFlags =
|
||||||
|
+ (DNS_QUERY_STANDARD | DNS_QUERY_NO_NETBT | DNS_QUERY_NO_HOSTS_FILE |
|
||||||
|
+ DNS_QUERY_NO_MULTICAST | DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE |
|
||||||
|
+ DNS_QUERY_DONT_RESET_TTL_VALUES);
|
||||||
|
unsigned int ttl = (unsigned int)-1;
|
||||||
|
- if (aAddressFamily == PR_AF_UNSPEC || aAddressFamily == PR_AF_INET) {
|
||||||
|
- _GetMinTTLForRequestType_Windows(aHost.BeginReading(), DNS_TYPE_A, &ttl);
|
||||||
|
- }
|
||||||
|
- if (aAddressFamily == PR_AF_UNSPEC || aAddressFamily == PR_AF_INET6) {
|
||||||
|
- _GetMinTTLForRequestType_Windows(aHost.BeginReading(), DNS_TYPE_AAAA, &ttl);
|
||||||
|
- }
|
||||||
|
+ _CallDnsQuery_A_Windows(
|
||||||
|
+ aHost, aAddressFamily, ttlFlags,
|
||||||
|
+ [&ttl, &aHost, aAddressFamily](PDNS_RECORDA curRecord) {
|
||||||
|
+ if (recordTypeMatchesRequest(curRecord->wType, aAddressFamily)) {
|
||||||
|
+ ttl = std::min<unsigned int>(ttl, curRecord->dwTtl);
|
||||||
|
+ } else {
|
||||||
|
+ LOG("Received unexpected record type %u in response for %s.\n",
|
||||||
|
+ curRecord->wType, aHost.BeginReading());
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
|
||||||
|
if (ttl == (unsigned int)-1) {
|
||||||
|
LOG("No useable TTL found.");
|
||||||
|
@@ -126,6 +158,41 @@
|
||||||
|
*aResult = ttl;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static MOZ_ALWAYS_INLINE nsresult
|
||||||
|
+_DNSQuery_A_SingleLabel(const nsACString& aCanonHost, uint16_t aAddressFamily,
|
||||||
|
+ uint16_t aFlags, AddrInfo** aAddrInfo) {
|
||||||
|
+ bool setCanonName = aFlags & nsHostResolver::RES_CANON_NAME;
|
||||||
|
+ nsAutoCString canonName;
|
||||||
|
+ const DWORD flags = (DNS_QUERY_STANDARD | DNS_QUERY_NO_MULTICAST |
|
||||||
|
+ DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE);
|
||||||
|
+ nsTArray<NetAddr> addresses;
|
||||||
|
+
|
||||||
|
+ _CallDnsQuery_A_Windows(
|
||||||
|
+ aCanonHost, aAddressFamily, flags, [&](PDNS_RECORDA curRecord) {
|
||||||
|
+ MOZ_DIAGNOSTIC_ASSERT(curRecord->wType == DNS_TYPE_A ||
|
||||||
|
+ curRecord->wType == DNS_TYPE_AAAA);
|
||||||
|
+ if (setCanonName) {
|
||||||
|
+ canonName.Assign(curRecord->pName);
|
||||||
|
+ }
|
||||||
|
+ NetAddr addr{};
|
||||||
|
+ addr.inet.family = AF_INET;
|
||||||
|
+ addr.inet.ip = curRecord->Data.A.IpAddress;
|
||||||
|
+ addresses.AppendElement(addr);
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ LOG("Query for: %s has %u results", aCanonHost.BeginReading(),
|
||||||
|
+ addresses.Length());
|
||||||
|
+ if (addresses.IsEmpty()) {
|
||||||
|
+ return NS_ERROR_UNKNOWN_HOST;
|
||||||
|
+ }
|
||||||
|
+ RefPtr<AddrInfo> ai(
|
||||||
|
+ new AddrInfo(aCanonHost, canonName, 0, std::move(addresses)));
|
||||||
|
+ ai.forget(aAddrInfo);
|
||||||
|
+
|
||||||
|
+ return NS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////
|
||||||
|
@@ -153,6 +220,24 @@
|
||||||
|
aAddressFamily = PR_AF_UNSPEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if defined(DNSQUERY_AVAILABLE)
|
||||||
|
+ if (StaticPrefs::network_dns_dns_query_single_label() &&
|
||||||
|
+ !aCanonHost.Contains('.') && aCanonHost != NS_LITERAL_CSTRING("localhost")) {
|
||||||
|
+ // For some reason we can't use DnsQuery_A to get the computer's IP.
|
||||||
|
+ if (!aCanonHost.Equals(nsDependentCString(sDNSComputerName),
|
||||||
|
+ nsCaseInsensitiveCStringComparator) &&
|
||||||
|
+ !aCanonHost.Equals(nsDependentCString(sNETBIOSComputerName),
|
||||||
|
+ nsCaseInsensitiveCStringComparator)) {
|
||||||
|
+ // This is a single label name resolve without a dot.
|
||||||
|
+ // We use DNSQuery_A for these.
|
||||||
|
+ LOG("Resolving %s using DnsQuery_A (computername: %s)\n",
|
||||||
|
+ aCanonHost.BeginReading(), sDNSComputerName);
|
||||||
|
+ return _DNSQuery_A_SingleLabel(aCanonHost, aAddressFamily, aFlags,
|
||||||
|
+ aAddrInfo);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
PRAddrInfo* prai =
|
||||||
|
PR_GetAddrInfoByName(aCanonHost.BeginReading(), aAddressFamily, prFlags);
|
||||||
|
|
||||||
|
@@ -184,6 +269,19 @@
|
||||||
|
//////////////////////////////////////
|
||||||
|
nsresult GetAddrInfoInit() {
|
||||||
|
LOG("Initializing GetAddrInfo.\n");
|
||||||
|
+
|
||||||
|
+#ifdef DNSQUERY_AVAILABLE
|
||||||
|
+ DWORD namesize = COMPUTER_NAME_BUFFER_SIZE;
|
||||||
|
+ if (!GetComputerNameEx(ComputerNameDnsHostname, sDNSComputerName,
|
||||||
|
+ &namesize)) {
|
||||||
|
+ sDNSComputerName[0] = 0;
|
||||||
|
+ }
|
||||||
|
+ namesize = MAX_COMPUTERNAME_LENGTH + 1;
|
||||||
|
+ if (!GetComputerNameEx(ComputerNameNetBIOS, sNETBIOSComputerName,
|
||||||
|
+ &namesize)) {
|
||||||
|
+ sNETBIOSComputerName[0] = 0;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -r 3e57839bffd2 -r 0344d5a76b7d netwerk/dns/moz.build
|
||||||
|
--- a/netwerk/dns/moz.build Fri Oct 30 10:19:14 2020 +0000
|
||||||
|
+++ b/netwerk/dns/moz.build Fri Oct 30 08:16:25 2020 +0000
|
||||||
|
@@ -54,6 +54,7 @@
|
||||||
|
]
|
||||||
|
|
||||||
|
SOURCES += [
|
||||||
|
+ 'GetAddrInfo.cpp', # Undefines UNICODE
|
||||||
|
'nsEffectiveTLDService.cpp', # Excluded from UNIFIED_SOURCES due to special build flags.
|
||||||
|
'nsHostResolver.cpp', # Redefines LOG
|
||||||
|
]
|
||||||
|
@@ -65,7 +66,6 @@
|
||||||
|
'DNSRequestChild.cpp',
|
||||||
|
'DNSRequestParent.cpp',
|
||||||
|
- 'GetAddrInfo.cpp',
|
||||||
|
'HTTPSSVC.cpp',
|
||||||
|
'IDNBlocklistUtils.cpp',
|
||||||
|
'NativeDNSResolverOverrideChild.cpp',
|
||||||
|
'NativeDNSResolverOverrideParent.cpp',
|
||||||
21
CVE-2020-26967.patch
Normal file
21
CVE-2020-26967.patch
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# User Kaizer Soze <kaizersoze915@gmail.com>
|
||||||
|
# Date 1602665311 0
|
||||||
|
# Wed Oct 14 08:48:31 2020 +0000
|
||||||
|
# Node ID 5a4b06d86f52685f2a4b51538f9ac3a7d9be265b
|
||||||
|
# Parent 1547b1a7189503e22eaa2180fa9597a044b91ff8
|
||||||
|
Bug 1665820, r=emalysz
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D92589
|
||||||
|
|
||||||
|
diff -r 1547b1a71895 -r 5a4b06d86f52 browser/extensions/screenshots/selector/ui.js
|
||||||
|
--- a/browser/extensions/screenshots/selector/ui.js Wed Oct 14 09:17:27 2020 +0000
|
||||||
|
+++ b/browser/extensions/screenshots/selector/ui.js Wed Oct 14 08:48:31 2020 +0000
|
||||||
|
@@ -361,6 +361,7 @@
|
||||||
|
this.element.setAttribute("role", "dialog");
|
||||||
|
this.element.onload = watchFunction(() => {
|
||||||
|
msgsPromise.then(([cancelTitle, copyTitle, downloadTitle]) => {
|
||||||
|
+ assertIsBlankDocument(this.element.contentDocument);
|
||||||
|
this.document = this.element.contentDocument;
|
||||||
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
|
this.document.documentElement.innerHTML = `
|
||||||
53
firefox.spec
53
firefox.spec
@ -88,7 +88,7 @@
|
|||||||
Summary: Mozilla Firefox Web browser
|
Summary: Mozilla Firefox Web browser
|
||||||
Name: firefox
|
Name: firefox
|
||||||
Version: 79.0
|
Version: 79.0
|
||||||
Release: 4
|
Release: 5
|
||||||
URL: https://www.mozilla.org/firefox/
|
URL: https://www.mozilla.org/firefox/
|
||||||
License: MPLv1.1 or GPLv2+ or LGPLv2+
|
License: MPLv1.1 or GPLv2+ or LGPLv2+
|
||||||
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}/source/firefox-%{version}.source.tar.xz
|
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}/source/firefox-%{version}.source.tar.xz
|
||||||
@ -153,6 +153,29 @@ Patch607: CVE-2020-15668.patch
|
|||||||
Patch608: CVE-2020-15676.patch
|
Patch608: CVE-2020-15676.patch
|
||||||
Patch609: CVE-2020-15677.patch
|
Patch609: CVE-2020-15677.patch
|
||||||
Patch610: CVE-2020-15678.patch
|
Patch610: CVE-2020-15678.patch
|
||||||
|
Patch611: CVE-2020-15969.patch
|
||||||
|
Patch612: CVE-2020-15999.patch
|
||||||
|
Patch613: CVE-2020-16012.patch
|
||||||
|
Patch614: CVE-2020-26951-1.patch
|
||||||
|
Patch615: CVE-2020-26951-2.patch
|
||||||
|
Patch616: CVE-2020-26953-pre.patch
|
||||||
|
Patch617: CVE-2020-26953.patch
|
||||||
|
Patch618: CVE-2020-26956-1.patch
|
||||||
|
Patch619: CVE-2020-26956-2.patch
|
||||||
|
Patch620: CVE-2020-26956-3.patch
|
||||||
|
Patch621: CVE-2020-26957.patch
|
||||||
|
Patch622: CVE-2020-26958.patch
|
||||||
|
Patch623: CVE-2020-26959.patch
|
||||||
|
Patch624: CVE-2020-26960-1.patch
|
||||||
|
Patch625: CVE-2020-26960-2.patch
|
||||||
|
Patch626: CVE-2020-26961-1.patch
|
||||||
|
Patch627: CVE-2020-26961-2.patch
|
||||||
|
Patch628: CVE-2020-26963-1.patch
|
||||||
|
Patch629: CVE-2020-26963-2.patch
|
||||||
|
Patch630: CVE-2020-26965.patch
|
||||||
|
Patch631: CVE-2020-26966.patch
|
||||||
|
Patch632: CVE-2020-26967.patch
|
||||||
|
|
||||||
%if %{?system_nss}
|
%if %{?system_nss}
|
||||||
BuildRequires: pkgconfig(nspr) >= %{nspr_version} pkgconfig(nss) >= %{nss_version}
|
BuildRequires: pkgconfig(nspr) >= %{nspr_version} pkgconfig(nss) >= %{nss_version}
|
||||||
BuildRequires: nss-static >= %{nss_version}
|
BuildRequires: nss-static >= %{nss_version}
|
||||||
@ -297,6 +320,28 @@ tar -xf %{SOURCE3}
|
|||||||
%patch608 -p1
|
%patch608 -p1
|
||||||
%patch609 -p1
|
%patch609 -p1
|
||||||
%patch610 -p1
|
%patch610 -p1
|
||||||
|
%patch611 -p1
|
||||||
|
%patch612 -p1
|
||||||
|
%patch613 -p1
|
||||||
|
%patch614 -p1
|
||||||
|
%patch615 -p1
|
||||||
|
%patch616 -p1
|
||||||
|
%patch617 -p1
|
||||||
|
%patch618 -p1
|
||||||
|
%patch619 -p1
|
||||||
|
%patch620 -p1
|
||||||
|
%patch621 -p1
|
||||||
|
%patch622 -p1
|
||||||
|
%patch623 -p1
|
||||||
|
%patch624 -p1
|
||||||
|
%patch625 -p1
|
||||||
|
%patch626 -p1
|
||||||
|
%patch627 -p1
|
||||||
|
%patch628 -p1
|
||||||
|
%patch629 -p1
|
||||||
|
%patch630 -p1
|
||||||
|
%patch631 -p1
|
||||||
|
%patch632 -p1
|
||||||
%{__rm} -f .mozconfig
|
%{__rm} -f .mozconfig
|
||||||
%{__cp} %{SOURCE10} .mozconfig
|
%{__cp} %{SOURCE10} .mozconfig
|
||||||
echo "ac_add_options --enable-default-toolkit=cairo-gtk3-wayland" >> .mozconfig
|
echo "ac_add_options --enable-default-toolkit=cairo-gtk3-wayland" >> .mozconfig
|
||||||
@ -738,6 +783,12 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jan 07 2021 wangxiao <wangxiao65@huawei.com> - 79.0-5
|
||||||
|
- Fix CVE-2020-15969 CVE-2020-15999 CVE-2020-16012 CVE-2020-26951
|
||||||
|
CVE-2020-26953 CVE-2020-26956 CVE-2020-26957 CVE-2020-26958
|
||||||
|
CVE-2020-26959 CVE-2020-26960 CVE-2020-26961 CVE-2020-26963
|
||||||
|
CVE-2020-26965 CVE-2020-25966 CVE-2020-26967
|
||||||
|
|
||||||
* Wed Dec 16 2020 wangxiao <wangxiao65@huawei.com> - 79.0-4
|
* Wed Dec 16 2020 wangxiao <wangxiao65@huawei.com> - 79.0-4
|
||||||
- Fix CVE-2020-15664 CVE-2020-15665 CVE-2020-15666 CVE-2020-15667
|
- Fix CVE-2020-15664 CVE-2020-15665 CVE-2020-15666 CVE-2020-15667
|
||||||
CVE-2020-15668 CVE-2020-15676 CVE-2020-15677 CVE-2020-15678
|
CVE-2020-15668 CVE-2020-15676 CVE-2020-15677 CVE-2020-15678
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user