Closed Bug 1962026 Opened 1 year ago Closed 1 year ago

Crash [@ EnterIon] due to mmap taking a bite out of the stack and interfering with fuzzing

Categories

(Core :: JavaScript Engine: JIT, defect, P3)

x86
Linux
defect

Tracking

()

RESOLVED FIXED
143 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr128 --- wontfix
firefox-esr140 --- wontfix
firefox139 --- wontfix
firefox140 --- wontfix
firefox141 --- wontfix
firefox142 --- wontfix
firefox143 --- fixed

People

(Reporter: sfink, Assigned: sfink)

References

Details

(Keywords: crash, sec-moderate, testcase, Whiteboard: [jsbugmon:ignore][fuzzblocker][adv-main143-])

Attachments

(1 file)

48 bytes, text/x-phabricator-request
Details | Review

Forked bug 909094. The problem is regarded as a fuzzblocker. This bug intends to sidestep that problem on fuzzing builds only by reserving the full potential stack in advance to prevent mmap from using any of it. When previously attempted on all builds, this caused worse problems than the original issue. So the strategy here is just get it out of the way of fuzzing; if a test case would have run into this, it will most likely OOM first. In no cases will it be able to crash anymore.

(It remains to be worked out exactly what this means for non-main threads.)

No longer blocks: 1269705
Severity: -- → S2
Priority: -- → P3
Whiteboard: [jsbugmon:ignore] → [jsbugmon:ignore][fuzzblocker]

I've implemented a version of this that seems to be working in the shell, at least. I take the current stack pointer and map the whole allowed JS stack space on startup. The new mapping will clobber a not yet used portion of the existing stack, which is fine. It behaves as a regular stack for C++ frames (as in, if you push onto the stack more than is mapped, it will automatically expand the stack and move the guard page down, at least until it hits another mapping.)

Some caveats:

  • In /proc/(pid)/maps, only the old mapping has the "[stack]" annotation. That is mostly cosmetic, though it might confuse tools that use that label to identify the stack mapping.
  • The new mapping could be changed to be executable, whereas the original mapping cannot. (As in, mprotect could add the PROT_EXEC bit.) This should be irrelevant for fuzzing, it would only be an issue if an attacker were to exploit it. (Though if an attacker can manage to get a rogue mprotect call, they've probably already broken in enough that it doesn't matter.) Apparently the Right Way to fix this is sandboxing.
  • This moves some memory from VmStk to VmData in proc/(self)/maps. I think that's also based on the (flawed) heuristic that labels one mapping "[stack]".
  • This bloats up the reported RSS usage by some amount. I'm not sure why; it doesn't happen immediately.
Attached file (secure)
Assignee: nobody → sphink
Status: NEW → ASSIGNED
Pushed by sfink@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/07c4fb6ddb8c https://hg.mozilla.org/integration/autoland/rev/d9800d753b74 On Linux fuzzing builds, reserve the full JS stack space on main thread startup r=decoder,jonco

https://hg.mozilla.org/mozilla-central/rev/d9800d753b74

Given that this only affects fuzzing builds, I don't see any need to uplift this.

Group: javascript-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 142 Branch
Regressions: 1977272
Pushed by chorotan@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/8526d2585980 https://hg.mozilla.org/integration/autoland/rev/de97b3b2a669 Revert "Bug 1962026 - On Linux fuzzing builds, reserve the full JS stack space on main thread startup r=decoder,jonco" on request
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Target Milestone: 142 Branch → ---

This looks like it didn't work because my "main stack only" check appears to have not worked, causing bug 1977272.

The PAC (ProxyAutoConfig) JSRuntime is started from a thread as the "main" runtime (parentRuntime=nullptr). I used this as a signal that we are on the process's main thread, and mmapped a big JS stack. That meant I clobbered whatever came before the PAC thread's stack -- causing delightfully weird crash stacks, fwiw. In the one I ended up looking at, I zeroed out a vtable and caused the next virtual method call on a totally different thread to crash. rr is truly a great tool.

Given that this is already linux-specific, I think maybe I can get away with just doing getpid() == gettid() and not trying to "fix" JS initialization stuff.

I have a test that changed behavior in linux32 (js/src/jit-test/tests/gc/bug-1459860.js). It used to get an over-recursion error. Now it's failing in pthread_create because the VM space is exhausted. Which is odd; I'm mapping an additional amount just above 1MB, and each thread is increasing the VmSize by 8MB, so the 1MB shouldn't matter much at all. But the VmSize is indeed climbing rapidly to 4GB and then failing.

...aw crud, the same thing is happening without my patches. Why... what... argh.

Oh! This appears to be bug 1978275. I should check my needinfos more frequently.

Duplicate of this bug: 1978275
No longer duplicate of this bug: 1978275
Duplicate of this bug: 1978275
Pushed by sfink@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/a08f5aa99c1b https://hg.mozilla.org/integration/autoland/rev/41742cc635fc On Linux fuzzing builds, reserve the full JS stack space on main thread startup r=decoder,jonco
Status: REOPENED → RESOLVED
Closed: 1 year ago1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 143 Branch

The patch landed in nightly and beta is affected.
:sfink, is this bug important enough to require an uplift?

For more information, please visit BugBot documentation.

Flags: needinfo?(sphink)
Flags: needinfo?(sphink)
QA Whiteboard: [qa-triage-done-c144/b143]
QA Whiteboard: [qa-triage-done-c144/b143] → [sec] [qa-triage-done-c144/b143]
Whiteboard: [jsbugmon:ignore][fuzzblocker] → [jsbugmon:ignore][fuzzblocker][adv-main143-]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: