AutoForbidPoolsAndNops is an RAII class available in at least the arm and
arm64 macro assemblers. It facilitates emitting small blocks of instructions
with the guarantee that the block won't be broken up for any reason.
Legitimate uses, as exemplified by the attached test patch, have been observed
to lead to the assertion failure:
Assertion failure: hasSpaceForInsts(maxInst, 0),
#0 AssemblerBufferWithConstantPools<..>::enterNoPool (this=0xffffffff67f0,
#1 MozBaseAssembler::enterNoPool (this=0xffffffff64c0, maxInst=5)
#3 0x0000aaaaabcb9c9c in js::jit::PreCallAssertions (masm=0xffffffff64c0)
- pull m-c and apply the test patch
- configure the shell thusly: --enable-debug --enable-optimize="-g -Og"
- run jit_tests: at least 3 tests should fail:
../src/jit-test/jit_test.py --no-xdr --args="" -f ./dist/bin/js
one of which is
Marking sec-low for now, because:
the assertion has to do with the relative placement of code and in-line data
so it's plausible to argue that it might be exploitable
the assertion that fails is not a release assert, hence the failure could be
silently missed in release builds
Why haven't we seen this before?
AutoForbidPoolsAndNops is used only
relatively infrequently. The test patch causes it to be used before many but
not all call instructions that SM generates. Because those are common, this
would represent a large increase in how often it is used, compared to
unpatched SM. And even then we get only 3 failures in circa 8700 tests done
So I am inclined to think: it's really a bug, but sufficiently obscure that
jit_tests doesn't uncover it. And release builds won't trigger the assertion
but presumably could fail some other, obscure way, as a result.