@ 261106.14 · fetching
current
/**
 * @license
 * Copyright 2019 The Emscripten Authors
 * SPDX-License-Identifier: MIT
 */

#if !STACK_OVERFLOW_CHECK
#error "should only be included in STACK_OVERFLOW_CHECK mode"
#endif

const stackCookie1 = 0x02135467;
const stackCookie2 = 0x89BACDFE;

// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode.
function writeStackCookie() {
  let max = _emscripten_stack_get_end();
#if RUNTIME_DEBUG
  dbg(`writeStackCookie: ${ptrToString(max)}`);
#endif
#if ASSERTIONS
  assert((max & 3) == 0);
#endif
  // If the stack ends at address zero we write our cookies 4 bytes into the
  // stack.  This prevents interference with SAFE_HEAP and ASAN which also
  // monitor writes to address zero.
  if (max == 0) {
    max += 4;
  }
  // The stack grow downwards towards _emscripten_stack_get_end.
  // We write cookies to the final two words in the stack and detect if they are
  // ever overwritten.
  {{{ makeSetValue('max', 0, 'stackCookie1', 'u32') }}};
  {{{ makeSetValue('max', 4, 'stackCookie2', 'u32') }}};
#if CHECK_NULL_WRITES
  // Also test the global address 0 for integrity.
  {{{ makeSetValue(0, 0, 0x63736d65 /* 'emsc' */, 'u32') }}};
#endif
}

function u32ToHexString(num) {
  return '0x' + (num >>> 0).toString(16).padStart(8, '0');
}

function checkStackCookie() {
#if !MINIMAL_RUNTIME
  if (ABORT) return;
#endif
  let max = _emscripten_stack_get_end();
#if RUNTIME_DEBUG >= 2
  dbg(`checkStackCookie: ${ptrToString(max)}`);
#endif
  // See writeStackCookie().
  if (max == 0) {
    max += 4;
  }
  const val1 = {{{ makeGetValue('max', 0, 'u32') }}};
  const val2 = {{{ makeGetValue('max', 4, 'u32') }}};
  if (val1 != stackCookie1 || val2 != stackCookie2) {
    abort(`Stack overflow! Stack cookie has been overwritten at ${ptrToString(max)}, expected hex dwords ${u32ToHexString(stackCookie2)} and ${u32ToHexString(stackCookie1)}, but received ${u32ToHexString(val2)} ${u32ToHexString(val1)}`);
  }
#if CHECK_NULL_WRITES
  // Also test the global address 0 for integrity.
  if ({{{ makeGetValue(0, 0, 'u32') }}} != 0x63736d65 /* 'emsc' */) {
    abort('Runtime error: The application has corrupted its heap memory area (address zero)!');
  }
#endif
}