diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-11-30 19:39:19 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-11-30 19:42:35 +0100 |
commit | 50dee79bfbe0782a342ef864b28d7d6613c0b1fb (patch) | |
tree | d7019c6315f71bd631f7efacf44ec92494922778 /src/shared/dns-domain.c | |
parent | c6cefd13eb55c8124a01e90021282f8610a05012 (diff) |
dns-domain: check resulting domain name length in dns_name_to_wire_format()
Let's better be safe than sorry.
Diffstat (limited to 'src/shared/dns-domain.c')
-rw-r--r-- | src/shared/dns-domain.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c index ba6eff8f60..03c0107308 100644 --- a/src/shared/dns-domain.c +++ b/src/shared/dns-domain.c @@ -864,7 +864,7 @@ bool dns_name_is_single_label(const char *name) { return dns_name_is_root(name); } -/* Encode a domain name according to RFC 1035 Section 3.1 */ +/* Encode a domain name according to RFC 1035 Section 3.1, without compression */ int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len) { uint8_t *label_length, *out; int r; @@ -875,24 +875,35 @@ int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len) { out = buffer; do { - /* reserve a byte for label length */ + /* Reserve a byte for label length */ if (len <= 0) return -ENOBUFS; len--; label_length = out; out++; - /* convert and copy a single label */ + /* Convert and copy a single label. Note that + * dns_label_unescape() returns 0 when it hits the end + * of the domain name, which we rely on here to encode + * the trailing NUL byte. */ r = dns_label_unescape(&domain, (char *) out, len); if (r < 0) return r; - /* fill label length, move forward */ + /* Fill label length, move forward */ *label_length = r; out += r; len -= r; + } while (r != 0); + /* Verify the maximum size of the encoded name. The trailing + * dot + NUL byte account are included this time, hence + * compare against DNS_HOSTNAME_MAX + 2 (which is 255) this + * time. */ + if (out - buffer > DNS_HOSTNAME_MAX + 2) + return -EINVAL; + return out - buffer; } |