(In reply to John Schanck [:jschanck] from comment #1) > I'm adding another signature which shows some evidence of memory corruption while processing an X.509 Name. This is a bit concerning since it might be easy to trigger remotely by sending a specially crafted certificate. > > I haven't been able to track down the exact cause. My current theory is that there is an error in [cert_RFC1485_GetRequiredLen](https://searchfox.org/mozilla-central/source/security/nss/lib/certdb/alg1485.c#604) and/or [escapeAndQuote](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#646). These two functions are called by [AppendAVA](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#911) (which is called shortly before the `CERT_NameToAsciiInvertible` crash) and [avaToString](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#1192) (which is called shortly before the `cert_GetCertificateEmailAddresses` crash).... Well, `escapeAndQuote()` does ``` [int] reqLen = cert_RFC1485_GetRequiredLen(src, srclen, &mode) + 1; ``` But `cert_RFC1485_GetRequiredLen()` can experience an integer overflow. since the largest value it effectively computes is `srclen*3 + 2` and `srclen` isa `int`. On return, `escapeAndQuote()` does ``` if (reqLen > dstlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } ``` But if `reqLen` has overflowed to negative, the condition will be `false` and `escapeAndQuote()` will write beyond bounds. Or `reqLen` could overflow to a small positive value, with the same consequences. The minimum value of `srclen` that can cause the overflow is `0x80000000 - 2 / 3` == `0x2aaaaaaa`. This is well within the maximum size of an `nsCString`, an `nsTArray<uint8_t>`, an `std::string`, etc. I don't know whether some other size check on this path prevents such a large `srclen` from getting to this code.
Bug 1748105 Comment 2 Edit History
Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.
(In reply to John Schanck [:jschanck] from comment #1) > I'm adding another signature which shows some evidence of memory corruption while processing an X.509 Name. This is a bit concerning since it might be easy to trigger remotely by sending a specially crafted certificate. > > I haven't been able to track down the exact cause. My current theory is that there is an error in [cert_RFC1485_GetRequiredLen](https://searchfox.org/mozilla-central/source/security/nss/lib/certdb/alg1485.c#604) and/or [escapeAndQuote](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#646). These two functions are called by [AppendAVA](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#911) (which is called shortly before the `CERT_NameToAsciiInvertible` crash) and [avaToString](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#1192) (which is called shortly before the `cert_GetCertificateEmailAddresses` crash).... Well, `escapeAndQuote()` does ``` [int] reqLen = cert_RFC1485_GetRequiredLen(src, srclen, &mode) + 1; ``` But `cert_RFC1485_GetRequiredLen()` can experience an integer overflow. since the largest value it effectively computes is `srclen*3 + 2` and `srclen` isa `int`. On return, `escapeAndQuote()` does ``` if (reqLen > dstlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } ``` But if `reqLen` has overflowed to negative, the condition will be `false` and `escapeAndQuote()` will write beyond bounds. Once that happens, all bets are off and you could get a "double free?" assertion or worse. Also `reqLen` could overflow to a small positive value, with the same consequences. The minimum value of `srclen` that can cause the overflow is `0x80000000 - 2 / 3` == `0x2aaaaaaa`. This is well within the maximum size of an `nsCString`, an `nsTArray<uint8_t>`, an `std::string`, etc. I don't know whether some other size check on this path prevents such a large `srclen` from getting to this code.
(In reply to John Schanck [:jschanck] from comment #1) > I'm adding another signature which shows some evidence of memory corruption while processing an X.509 Name. This is a bit concerning since it might be easy to trigger remotely by sending a specially crafted certificate. > > I haven't been able to track down the exact cause. My current theory is that there is an error in [cert_RFC1485_GetRequiredLen](https://searchfox.org/mozilla-central/source/security/nss/lib/certdb/alg1485.c#604) and/or [escapeAndQuote](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#646). These two functions are called by [AppendAVA](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#911) (which is called shortly before the `CERT_NameToAsciiInvertible` crash) and [avaToString](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#1192) (which is called shortly before the `cert_GetCertificateEmailAddresses` crash).... Well, `escapeAndQuote()` does ``` [int] reqLen = cert_RFC1485_GetRequiredLen(src, srclen, &mode) + 1; ``` But `cert_RFC1485_GetRequiredLen()` can experience an integer overflow. since the largest value it effectively computes is `srclen*3 + 2` and `srclen` isa `int`. On return, `escapeAndQuote()` does ``` if (reqLen > dstlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } ``` But if `reqLen` has overflowed to negative, the condition will be `false` and `escapeAndQuote()` will write beyond bounds. Once that happens, all bets are off and you could get a "double free?" assertion or worse.(Your mention of "evidence of memory corruption" is also consistent with this mechanism). Also `reqLen` could overflow to a small positive value, with the same consequences. The minimum value of `srclen` that can cause the overflow is `0x80000000 - 2 / 3` == `0x2aaaaaaa`. This is well within the maximum size of an `nsCString`, an `nsTArray<uint8_t>`, an `std::string`, etc. I don't know whether some other size check on this path prevents such a large `srclen` from getting to this code.
(In reply to John Schanck [:jschanck] from comment #1) > I'm adding another signature which shows some evidence of memory corruption while processing an X.509 Name. This is a bit concerning since it might be easy to trigger remotely by sending a specially crafted certificate. > > I haven't been able to track down the exact cause. My current theory is that there is an error in [cert_RFC1485_GetRequiredLen](https://searchfox.org/mozilla-central/source/security/nss/lib/certdb/alg1485.c#604) and/or [escapeAndQuote](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#646). These two functions are called by [AppendAVA](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#911) (which is called shortly before the `CERT_NameToAsciiInvertible` crash) and [avaToString](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#1192) (which is called shortly before the `cert_GetCertificateEmailAddresses` crash).... Well, `escapeAndQuote()` does ``` [int] reqLen = cert_RFC1485_GetRequiredLen(src, srclen, &mode) + 1; ``` But `cert_RFC1485_GetRequiredLen()` can experience an integer overflow, since it can compute a value as large is `srclen*3 + 2` and `srclen` isa `int`. On return, `escapeAndQuote()` does ``` if (reqLen > dstlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } ``` But if `reqLen` has overflowed to negative, the condition will be `false` and `escapeAndQuote()` will write beyond bounds. Once that happens, all bets are off and you could get a "double free?" assertion or worse.(Your mention of "evidence of memory corruption" is also consistent with this mechanism). Also `reqLen` could overflow to a small positive value, with the same consequences. The minimum value of `srclen` that can cause the overflow is `0x80000000 - 2 / 3` == `0x2aaaaaaa`. This is well within the maximum size of an `nsCString`, an `nsTArray<uint8_t>`, an `std::string`, etc. I don't know whether some other size check on this path prevents such a large `srclen` from getting to this code.
(In reply to John Schanck [:jschanck] from comment #1) > I'm adding another signature which shows some evidence of memory corruption while processing an X.509 Name. This is a bit concerning since it might be easy to trigger remotely by sending a specially crafted certificate. > > I haven't been able to track down the exact cause. My current theory is that there is an error in [cert_RFC1485_GetRequiredLen](https://searchfox.org/mozilla-central/source/security/nss/lib/certdb/alg1485.c#604) and/or [escapeAndQuote](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#646). These two functions are called by [AppendAVA](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#911) (which is called shortly before the `CERT_NameToAsciiInvertible` crash) and [avaToString](https://searchfox.org/mozilla-central/rev/0e3d9bfae6fdaa6cb29cbce3f25471d5708aedc3/security/nss/lib/certdb/alg1485.c#1192) (which is called shortly before the `cert_GetCertificateEmailAddresses` crash).... Well, `escapeAndQuote()` does ``` [int] reqLen = cert_RFC1485_GetRequiredLen(src, srclen, &mode) + 1; ``` But `cert_RFC1485_GetRequiredLen()` can experience an integer overflow, since it can compute a value as large as `srclen*3 + 2` and `srclen` isa `int`. On return, `escapeAndQuote()` does ``` if (reqLen > dstlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); return SECFailure; } ``` But if `reqLen` has overflowed to negative, the condition will be `false` and `escapeAndQuote()` will write beyond bounds. Once that happens, all bets are off and you could get a "double free?" assertion or worse.(Your mention of "evidence of memory corruption" is also consistent with this mechanism). Also `reqLen` could overflow to a small positive value, with the same consequences. The minimum value of `srclen` that can cause the overflow is `0x80000000 - 2 / 3` == `0x2aaaaaaa`. This is well within the maximum size of an `nsCString`, an `nsTArray<uint8_t>`, an `std::string`, etc. I don't know whether some other size check on this path prevents such a large `srclen` from getting to this code.