mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 09:21:26 +03:00
dns-domain: check resulting domain name length in dns_name_to_wire_format()
Let's better be safe than sorry.
This commit is contained in:
parent
c6cefd13eb
commit
50dee79bfb
@ -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;
|
||||
}
|
||||
|
||||
|
@ -66,10 +66,36 @@ static void test_dns_name_to_wire_format_one(const char *what, const char *expec
|
||||
}
|
||||
|
||||
static void test_dns_name_to_wire_format(void) {
|
||||
const char out0[] = { 0 };
|
||||
const char out1[] = { 3, 'f', 'o', 'o', 0 };
|
||||
const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
|
||||
const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
|
||||
static const char out0[] = { 0 };
|
||||
static const char out1[] = { 3, 'f', 'o', 'o', 0 };
|
||||
static const char out2[] = { 5, 'h', 'a', 'l', 'l', 'o', 3, 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
|
||||
static const char out3[] = { 4, ' ', 'f', 'o', 'o', 3, 'b', 'a', 'r', 0 };
|
||||
static const char out4[] = { 9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
9, 'a', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
3, 'a', '1', '2', 0 };
|
||||
|
||||
test_dns_name_to_wire_format_one("", out0, sizeof(out0), sizeof(out0));
|
||||
|
||||
@ -81,6 +107,9 @@ static void test_dns_name_to_wire_format(void) {
|
||||
test_dns_name_to_wire_format_one("hallo.foo..bar", NULL, 32, -EINVAL);
|
||||
|
||||
test_dns_name_to_wire_format_one("\\032foo.bar", out3, sizeof(out3), sizeof(out3));
|
||||
|
||||
test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", NULL, 500, -EINVAL);
|
||||
test_dns_name_to_wire_format_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", out4, sizeof(out4), sizeof(out4));
|
||||
}
|
||||
|
||||
static void test_dns_label_unescape_suffix_one(const char *what, const char *expect1, const char *expect2, size_t buffer_sz, int ret1, int ret2) {
|
||||
|
Loading…
Reference in New Issue
Block a user