resolved: fix memleak of gcrypt context on error

Bug found by Stef Bon <stefbon@gmail.com>. Thanks!
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2018-02-05 10:06:36 +01:00
parent bd944e6e18
commit 8530efc1c3

View file

@ -716,7 +716,7 @@ int dnssec_verify_rrset(
uint8_t wire_format_name[DNS_WIRE_FOMAT_HOSTNAME_MAX]; uint8_t wire_format_name[DNS_WIRE_FOMAT_HOSTNAME_MAX];
DnsResourceRecord **list, *rr; DnsResourceRecord **list, *rr;
const char *source, *name; const char *source, *name;
gcry_md_hd_t md = NULL; _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
int r, md_algorithm; int r, md_algorithm;
size_t k, n = 0; size_t k, n = 0;
size_t sig_size = 0; size_t sig_size = 0;
@ -841,13 +841,13 @@ int dnssec_verify_rrset(
r = dns_name_to_wire_format(rrsig->rrsig.signer, wire_format_name, sizeof(wire_format_name), true); r = dns_name_to_wire_format(rrsig->rrsig.signer, wire_format_name, sizeof(wire_format_name), true);
if (r < 0) if (r < 0)
goto finish; return r;
fwrite(wire_format_name, 1, r, f); fwrite(wire_format_name, 1, r, f);
/* Convert the source of synthesis into wire format */ /* Convert the source of synthesis into wire format */
r = dns_name_to_wire_format(source, wire_format_name, sizeof(wire_format_name), true); r = dns_name_to_wire_format(source, wire_format_name, sizeof(wire_format_name), true);
if (r < 0) if (r < 0)
goto finish; return r;
for (k = 0; k < n; k++) { for (k = 0; k < n; k++) {
size_t l; size_t l;
@ -885,26 +885,20 @@ int dnssec_verify_rrset(
#endif #endif
case DNSSEC_ALGORITHM_ED448: case DNSSEC_ALGORITHM_ED448:
*result = DNSSEC_UNSUPPORTED_ALGORITHM; *result = DNSSEC_UNSUPPORTED_ALGORITHM;
r = 0; return 0;
goto finish;
default: default:
/* OK, the RRs are now in canonical order. Let's calculate the digest */ /* OK, the RRs are now in canonical order. Let's calculate the digest */
md_algorithm = algorithm_to_gcrypt_md(rrsig->rrsig.algorithm); md_algorithm = algorithm_to_gcrypt_md(rrsig->rrsig.algorithm);
if (md_algorithm == -EOPNOTSUPP) { if (md_algorithm == -EOPNOTSUPP) {
*result = DNSSEC_UNSUPPORTED_ALGORITHM; *result = DNSSEC_UNSUPPORTED_ALGORITHM;
r = 0; return 0;
goto finish;
}
if (md_algorithm < 0) {
r = md_algorithm;
goto finish;
} }
if (md_algorithm < 0)
return md_algorithm;
gcry_md_open(&md, md_algorithm, 0); gcry_md_open(&md, md_algorithm, 0);
if (!md) { if (!md)
r = -EIO; return -EIO;
goto finish;
}
hash_size = gcry_md_get_algo_dlen(md_algorithm); hash_size = gcry_md_get_algo_dlen(md_algorithm);
assert(hash_size > 0); assert(hash_size > 0);
@ -912,10 +906,8 @@ int dnssec_verify_rrset(
gcry_md_write(md, sig_data, sig_size); gcry_md_write(md, sig_data, sig_size);
hash = gcry_md_read(md, 0); hash = gcry_md_read(md, 0);
if (!hash) { if (!hash)
r = -EIO; return -EIO;
goto finish;
}
} }
switch (rrsig->rrsig.algorithm) { switch (rrsig->rrsig.algorithm) {
@ -950,9 +942,8 @@ int dnssec_verify_rrset(
break; break;
#endif #endif
} }
if (r < 0) if (r < 0)
goto finish; return r;
/* Now, fix the ttl, expiry, and remember the synthesizing source and the signer */ /* Now, fix the ttl, expiry, and remember the synthesizing source and the signer */
if (r > 0) if (r > 0)
@ -965,13 +956,7 @@ int dnssec_verify_rrset(
else else
*result = DNSSEC_VALIDATED; *result = DNSSEC_VALIDATED;
r = 0; return 0;
finish:
if (md)
gcry_md_close(md);
return r;
} }
int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey, bool revoked_ok) { int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey, bool revoked_ok) {