From 0f84a72e3c0f58d71cff2121e6df1611eaf9c9ea Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Thu, 27 Nov 2014 16:08:46 +0100 Subject: [PATCH 1/1] resolve: fix NULL deref on strv comparison MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit A strv might be NULL if it is empty. The txt.strings comparison doesn't take that into account. Introduce strv_equal() to provide a proper helper for this and fix resolve to use it. Thanks to Stanisław Pitucha for reporting this! --- src/resolve/resolved-dns-rr.c | 10 ++-------- src/shared/strv.c | 11 +++++++++++ src/shared/strv.h | 2 ++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index fd5ecf413..78d9e4a41 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -370,14 +370,8 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor strcaseeq(a->hinfo.os, b->hinfo.os); case DNS_TYPE_SPF: /* exactly the same as TXT */ - case DNS_TYPE_TXT: { - int i; - - for (i = 0; a->txt.strings[i] || b->txt.strings[i]; i++) - if (!streq_ptr(a->txt.strings[i], b->txt.strings[i])) - return false; - return true; - } + case DNS_TYPE_TXT: + return strv_equal(a->txt.strings, b->txt.strings); case DNS_TYPE_A: return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0; diff --git a/src/shared/strv.c b/src/shared/strv.c index aeb93eac6..a5f8a2aff 100644 --- a/src/shared/strv.c +++ b/src/shared/strv.c @@ -587,6 +587,17 @@ char **strv_sort(char **l) { return l; } +bool strv_equal(char **a, char **b) { + if (!a || !b) + return a == b; + + for ( ; *a || *b; ++a, ++b) + if (!streq_ptr(*a, *b)) + return false; + + return true; +} + void strv_print(char **l) { char **s; diff --git a/src/shared/strv.h b/src/shared/strv.h index 47618bd26..774c67a8c 100644 --- a/src/shared/strv.h +++ b/src/shared/strv.h @@ -49,6 +49,8 @@ int strv_consume_prepend(char ***l, char *value); char **strv_remove(char **l, const char *s); char **strv_uniq(char **l); +bool strv_equal(char **a, char **b); + #define strv_contains(l, s) (!!strv_find((l), (s))) char **strv_new(const char *x, ...) _sentinel_; -- 2.30.2