Fix X509_parse_from_buffer when failing to parse.
d2i_X509 will free an existing |X509*| on parse failure. Thus |X509_parse_from_buffer| would double-free the result on error. Change-Id: If2bca2f1e1895bc426079f6ade4b82008707888d Reviewed-on: https://boringssl-review.googlesource.com/12635 Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: Adam Langley <agl@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
parent
9d125dcdec
commit
c8006be227
@ -940,6 +940,50 @@ static bool TestFromBufferReused() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool TestFailedParseFromBuffer() {
|
||||||
|
static const uint8_t kNonsense[] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
|
bssl::UniquePtr<CRYPTO_BUFFER> buf(
|
||||||
|
CRYPTO_BUFFER_new(kNonsense, sizeof(kNonsense), nullptr));
|
||||||
|
if (!buf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bssl::UniquePtr<X509> cert(X509_parse_from_buffer(buf.get()));
|
||||||
|
if (cert) {
|
||||||
|
fprintf(stderr, "Nonsense somehow parsed.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
|
// Test a buffer with trailing data.
|
||||||
|
size_t data_len;
|
||||||
|
bssl::UniquePtr<uint8_t> data;
|
||||||
|
if (!PEMToDER(&data, &data_len, kRootCAPEM)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<uint8_t[]> data_with_trailing_byte(new uint8_t[data_len + 1]);
|
||||||
|
memcpy(data_with_trailing_byte.get(), data.get(), data_len);
|
||||||
|
data_with_trailing_byte[data_len] = 0;
|
||||||
|
|
||||||
|
bssl::UniquePtr<CRYPTO_BUFFER> buf_with_trailing_byte(
|
||||||
|
CRYPTO_BUFFER_new(data_with_trailing_byte.get(), data_len + 1, nullptr));
|
||||||
|
if (!buf_with_trailing_byte) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bssl::UniquePtr<X509> root(
|
||||||
|
X509_parse_from_buffer(buf_with_trailing_byte.get()));
|
||||||
|
if (root) {
|
||||||
|
fprintf(stderr, "Parsed buffer with trailing byte.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
CRYPTO_library_init();
|
CRYPTO_library_init();
|
||||||
|
|
||||||
@ -951,7 +995,8 @@ int main() {
|
|||||||
!TestFromBuffer() ||
|
!TestFromBuffer() ||
|
||||||
!TestFromBufferTrailingData() ||
|
!TestFromBufferTrailingData() ||
|
||||||
!TestFromBufferModified() ||
|
!TestFromBufferModified() ||
|
||||||
!TestFromBufferReused()) {
|
!TestFromBufferReused() ||
|
||||||
|
!TestFailedParseFromBuffer()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +162,8 @@ X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) {
|
|||||||
X509 *x509p = x509;
|
X509 *x509p = x509;
|
||||||
X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf));
|
X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf));
|
||||||
if (ret == NULL ||
|
if (ret == NULL ||
|
||||||
(inp - CRYPTO_BUFFER_data(buf)) != (ptrdiff_t) CRYPTO_BUFFER_len(buf)) {
|
inp - CRYPTO_BUFFER_data(buf) != (ptrdiff_t)CRYPTO_BUFFER_len(buf)) {
|
||||||
X509_free(x509);
|
X509_free(x509p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
assert(x509p == x509);
|
assert(x509p == x509);
|
||||||
|
Loading…
Reference in New Issue
Block a user