diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index 67cf991e705..575f100809d 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -554,7 +554,12 @@ static void dnssec_fix_rrset_ttl( /* Pick the TTL as the minimum of the RR's TTL, the * RR's original TTL according to the RRSIG and the * RRSIG's own TTL, see RFC 4035, Section 5.3.3 */ - rr->ttl = MIN3(rr->ttl, rrsig->rrsig.original_ttl, rrsig->ttl); + uint32_t ttl = MIN3(rr->ttl, rrsig->rrsig.original_ttl, rrsig->ttl); + if (ttl != rr->ttl) { + rr->ttl = ttl; + dns_resource_record_clear_wire_format(rr); + } + rr->expiry = rrsig->rrsig.expiration * USEC_PER_SEC; /* Copy over information about the signer and wildcard source of synthesis */ diff --git a/src/resolve/test-dns-rr.c b/src/resolve/test-dns-rr.c index d77ae0639d8..834c100b076 100644 --- a/src/resolve/test-dns-rr.c +++ b/src/resolve/test-dns-rr.c @@ -2467,18 +2467,29 @@ TEST(dns_resource_record_is_synthetic) { * ================================================================ */ TEST(dns_resource_record_clamp_ttl_in_place) { + _cleanup_free_ void *wire_format = NULL; DnsResourceRecord *rr = NULL, *orig = NULL; + size_t wire_format_size; rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"); ASSERT_NOT_NULL(rr); orig = rr; rr->ttl = 3600; + rr->a.in_addr.s_addr = htobe32(0xc0a8017f); ASSERT_FALSE(dns_resource_record_clamp_ttl(&rr, 4800)); ASSERT_EQ(rr->ttl, 3600u); + ASSERT_OK(dns_resource_record_to_wire_format(rr, false)); + ASSERT_NOT_NULL(rr->wire_format); + wire_format_size = rr->wire_format_size; + ASSERT_NOT_NULL(wire_format = memdup(rr->wire_format, wire_format_size)); + ASSERT_TRUE(dns_resource_record_clamp_ttl(&rr, 2400)); ASSERT_EQ(rr->ttl, 2400u); + ASSERT_OK(dns_resource_record_to_wire_format(rr, false)); + ASSERT_EQ(rr->wire_format_size, wire_format_size); + ASSERT_NE(memcmp(rr->wire_format, wire_format, wire_format_size), 0); ASSERT_TRUE(rr == orig); diff --git a/src/shared/dns-rr.c b/src/shared/dns-rr.c index d5941662906..74be11cded5 100644 --- a/src/shared/dns-rr.c +++ b/src/shared/dns-rr.c @@ -1466,6 +1466,15 @@ int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) { return 0; } +void dns_resource_record_clear_wire_format(DnsResourceRecord *rr) { + assert(rr); + + rr->wire_format = mfree(rr->wire_format); + rr->wire_format_size = 0; + rr->wire_format_rdata_offset = 0; + rr->wire_format_canonical = false; +} + int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret) { const char *n; int r; @@ -1977,6 +1986,7 @@ int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl) { if (old_rr->n_ref == 1) { /* Patch in place */ old_rr->ttl = new_ttl; + dns_resource_record_clear_wire_format(old_rr); return 1; } diff --git a/src/shared/dns-rr.h b/src/shared/dns-rr.h index d747083aa8a..a3cde2f3d1e 100644 --- a/src/shared/dns-rr.h +++ b/src/shared/dns-rr.h @@ -392,6 +392,7 @@ const char* dns_resource_record_to_string(DnsResourceRecord *rr); DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr); DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref); +void dns_resource_record_clear_wire_format(DnsResourceRecord *rr); int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical); int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret); diff --git a/src/shared/efi-api.c b/src/shared/efi-api.c index 56b055a0c8a..652c48e84ba 100644 --- a/src/shared/efi-api.c +++ b/src/shared/efi-api.c @@ -283,19 +283,23 @@ int efi_get_boot_option( if (header->path_len > 0) { uint8_t *dbuf; - size_t dnext, doff; + size_t dnext, doff, path_len; doff = offsetof(struct boot_option, title) + title_size; dbuf = buf + doff; - if (header->path_len > l - doff) - return -EINVAL; + path_len = MIN((size_t) header->path_len, l - doff); dnext = 0; - while (dnext < header->path_len) { + while (dnext < path_len) { struct device_path *dpath; + size_t remaining = path_len - dnext; + + if (remaining < offsetof(struct device_path, path)) + break; dpath = (struct device_path *)(dbuf + dnext); - if (dpath->length < 4) + if (dpath->length < offsetof(struct device_path, path) || + dpath->length > remaining) break; /* Type 0x7F – End of Hardware Device Path, Sub-Type 0xFF – End Entire Device Path */ @@ -310,6 +314,9 @@ int efi_get_boot_option( /* Sub-Type 1 – Hard Drive */ if (dpath->sub_type == MEDIA_HARDDRIVE_DP) { + if (dpath->length < offsetof(struct device_path, drive) + sizeof(struct drive_path)) + break; + /* 0x02 – GUID Partition Table */ if (dpath->drive.mbr_type != MBR_TYPE_EFI_PARTITION_TABLE_HEADER) continue; @@ -325,9 +332,9 @@ int efi_get_boot_option( /* Sub-Type 4 – File Path */ if (dpath->sub_type == MEDIA_FILEPATH_DP && !p && ret_path) { - p = utf16_to_utf8(dpath->path, dpath->length-4); + p = utf16_to_utf8(dpath->path, dpath->length - offsetof(struct device_path, path)); if (!p) - return -ENOMEM; + return -ENOMEM; efi_tilt_backslashes(p); continue;