summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/icecat-CVE-2016-2805.patch
blob: 5e4150f00cd64b5f3040bc5a23ebcc2e22c36e97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/bf34b97757b3

# HG changeset patch
# User Jon Coppeard <jcoppeard@mozilla.com>
# Date 1453890675 0
# Node ID bf34b97757b334af1f9f53b9b59e0b6902e7ed6f
# Parent  228ca3f46cabaf3f388f6c6640690772aa13c1a5
Bug 1241731 - Handle incomplete buffer in DiscardTransferables r=sfink a=abillings a=sylvestre

diff --git a/js/src/jit-test/tests/gc/bug-1241731.js b/js/src/jit-test/tests/gc/bug-1241731.js
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1241731.js
@@ -0,0 +1,4 @@
+if (!('oomTest' in this))
+    quit();
+
+oomTest(() => serialize(0, [{}]));
diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -379,39 +379,50 @@ ReadStructuredClone(JSContext* cx, uint6
 
 // If the given buffer contains Transferables, free them. Note that custom
 // Transferables will use the JSStructuredCloneCallbacks::freeTransfer() to
 // delete their transferables.
 static void
 Discard(uint64_t* buffer, size_t nbytes, const JSStructuredCloneCallbacks* cb, void* cbClosure)
 {
     MOZ_ASSERT(nbytes % sizeof(uint64_t) == 0);
-    if (nbytes < sizeof(uint64_t))
+    uint64_t* end = buffer + nbytes / sizeof(uint64_t);
+    uint64_t* point = buffer;
+    if (point == end)
         return; // Empty buffer
 
-    uint64_t* point = buffer;
     uint32_t tag, data;
     SCInput::getPair(point++, &tag, &data);
     if (tag != SCTAG_TRANSFER_MAP_HEADER)
         return;
 
     if (TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED)
         return;
 
     // freeTransfer should not GC
     JS::AutoSuppressGCAnalysis nogc;
 
+    if (point == end)
+        return;
+
     uint64_t numTransferables = LittleEndian::readUint64(point++);
     while (numTransferables--) {
+        if (point == end)
+            return;
+
         uint32_t ownership;
         SCInput::getPair(point++, &tag, &ownership);
         MOZ_ASSERT(tag >= SCTAG_TRANSFER_MAP_PENDING_ENTRY);
+        if (point == end)
+            return;
 
         void* content;
         SCInput::getPtr(point++, &content);
+        if (point == end)
+            return;
 
         uint64_t extraData = LittleEndian::readUint64(point++);
 
         if (ownership < JS::SCTAG_TMO_FIRST_OWNED)
             continue;
 
         if (ownership == JS::SCTAG_TMO_ALLOC_DATA) {
             js_free(content);