chiark / gitweb /
resolve: fix NULL deref on strv comparison
authorDavid Herrmann <dh.herrmann@gmail.com>
Thu, 27 Nov 2014 15:08:46 +0000 (16:08 +0100)
committerDavid Herrmann <dh.herrmann@gmail.com>
Thu, 27 Nov 2014 15:10:44 +0000 (16:10 +0100)
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 <viraptor@gmail.com> for reporting this!

src/resolve/resolved-dns-rr.c
src/shared/strv.c
src/shared/strv.h

index fd5ecf413dc76921b3c6f72783ba8b79bf16cf24..78d9e4a412471458ab1004be2e96724c76614b9c 100644 (file)
@@ -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;
index aeb93eac6b0fabdd155a22a73ee3004bb1cc0ce7..a5f8a2aff60e3ea36c82998c0f43e003717efbdb 100644 (file)
@@ -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;
 
index 47618bd26c8c44099e463ad6cdb5fd7466109d51..774c67a8c81bfff6f114a29f9383d2a92fc46a1f 100644 (file)
@@ -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_;