Out-of-Bounds Read in ML-DSA Private Key Parsing (zero-length privateKey)
Categories
(NSS :: Libraries, defect)
Tracking
(firefox-esr115 wontfix, firefox-esr140 wontfix, firefox147 wontfix, firefox148 wontfix, firefox149 fixed)
People
(Reporter: cy1yang, Assigned: anna.weine, NeedInfo)
References
Details
(5 keywords, Whiteboard: [adv-main149+])
Attachments
(2 files, 1 external file)
Steps to reproduce:
-
Use our generated P12 file (
malformed_mldsa.p12) -
Open Firefox (Nightly or a build with ML-DSA support)
-
Navigate to Certificate Manager:
Settings → Privacy & Security → Certificates → View Certificates...Or enter
about:preferences#privacyin the address bar and scroll to "Certificates" -
Click "Import..." Under "Your Certificates" button in the Certificate Manager dialog
-
Select the file:
malformed_mldsa.p12 -
Enter password: Leave empty (just press Enter/OK)
Actual results:
Firefox will crash or become unresponsive when attempting to import the malformed certificate. On systems with crash reporting enabled, a crash report will be generated.
Analysis
Out-of-bounds read in NSS when parsing ML-DSA (post-quantum) private keys. Both PK11_ImportPrivateKeyInfoAndReturnKey() (pk11pk12.c:763) and sftk_unwrapPrivateKey() (pkcs11c.c:7215) access pki->privateKey.data[0] without validating pki->privateKey.len > 0. A PKCS#12 file with an empty privateKey OCTET STRING (04 00) triggers the bug during import.
Affected Code
Location 1: pk11pk12.c:763
case SEC_OID_ML_DSA_44:
case SEC_OID_ML_DSA_65:
case SEC_OID_ML_DSA_87:
/* choice */
switch (pki->privateKey.data[0]) { // OOB READ if privateKey.len == 0
case SEC_ASN1_CONTEXT_SPECIFIC | 0:
keyTemplate = SECKEY_MLDSAPrivateKeySeedExportTemplate;
break;
// ...
}
Location 2: pkcs11c.c:7215
case SEC_OID_ML_DSA_44_PUBLIC_KEY:
case SEC_OID_ML_DSA_65_PUBLIC_KEY:
case SEC_OID_ML_DSA_87_PUBLIC_KEY:
mldsa_next:
switch (pki->privateKey.data[0]) { // OOB READ if privateKey.len == 0
// ...
}
Expected results:
The code should validate pki->privateKey.len > 0 before accessing pki->privateKey.data[0] and return an appropriate error (e.g., SEC_ERROR_BAD_DER).
| Reporter | ||
Comment 1•10 months ago
|
||
| Assignee | ||
Comment 2•10 months ago
|
||
Hi,
Thanks for the report. I can reproduce the bug. We will take a look at it.
| Assignee | ||
Comment 4•10 months ago
|
||
Updated•10 months ago
|
Comment 5•10 months ago
•
|
||
Anna and I took a very quick look at the pkcs12 fuzzer which uses the same set of functions as the certificate import code. The provided test case doesn't error for the fuzzer, so we should figure out why we're missing that coverage.
Comment 6•10 months ago
|
||
Dennis, is the fuzzer completely random, or does it work off valid data that is then corrupted?
If it's the former, then it probably didn't trigger because you need most of the input to be valid, including a valid ml-dsa oid (which is one of 3 very specific values).
If it's the latter, we probably don't have a valid ml-dsa p12 as a base. If you didn't have the ml-dsa as the base, then you're unlikely to get one of the ml-dsa oids and thus unlikely to trip the code.
Comment 7•10 months ago
|
||
I didn't have time to look in detail yet, but I provided the attached test case to the fuzzer directly so it's not a question of randomness. The code run by the fuzzer and by the Fx import dialog should be equivalent (but presumably aren't).
| Assignee | ||
Comment 8•10 months ago
|
||
(In reply to Dennis Jackson from comment #7)
I didn't have time to look in detail yet, but I provided the attached test case to the fuzzer directly so it's not a question of randomness. The code run by the fuzzer and by the Fx import dialog should be equivalent (but presumably aren't).
Just to be sure, you're able to reproduce the bug?
Updated•10 months ago
|
Pushed by nkulatova@mozilla.com:
https://hg.mozilla.org/projects/nss/rev/a4e63cad50cc
Out-of-Bounds Read in ML-DSA Private Key Parsing (zero-length privateKey) r=nss-reviewers,rrelyea
Updated•9 months ago
|
Updated•9 months ago
|
Comment 10•9 months ago
•
|
||
AFAIU the problematic function is SEC_PKCS12DecoderImportBags, but when running the the PKCS12 fuzzer with the certificate generated by generate_poc.py, it doesn't get pass SEC_PKCS12DecoderVerify. sec_pkcs12_decoder_verify_mac returns SECFailure, but I can't figure out why. Am I missing something?
Updated•8 months ago
|
Updated•7 months ago
|
Comment 11•7 months ago
|
||
Cody / cy1yang: By default our advisories will credit you as Cody using your Bugzilla profile "real name" field. If you would like to be credited differently please let us know here. If you do, check the "request information from" box below, leave the "other" input as-is, and enter :tsmith in the blank input field. It should autocomplete with Tyson's mozilla.com address.
Comment 12•7 months ago
|
||
The report says OOB read, but if pki->privateKey.len == 0, then pki->privateKey.data should be NULL, or am I missing something?
Updated•7 months ago
|
Comment 13•7 months ago
|
||
status-firefox-esr140: --- → fix-optional
shouldn't this be "unaffected" ? AFAICT, esr140 doesn't support ML-DSA.
Updated•6 months ago
|
Updated•3 months ago
|
Description
•