From 20011324500a728851e4888c890a756ecf71394b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 27 Oct 2005 14:30:46 +0000 Subject: Add validity checking to TXT data parsing, this fixes a remotely exploitable vulnerability. git-svn-id: file:///home/lennart/svn/public/avahi/trunk@888 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/strlst-test.c | 4 ++-- avahi-common/strlst.c | 38 +++++++++++++++++++++++++++----------- avahi-common/strlst.h | 2 +- 3 files changed, 30 insertions(+), 14 deletions(-) (limited to 'avahi-common') diff --git a/avahi-common/strlst-test.c b/avahi-common/strlst-test.c index 68dc472..3cdcb12 100644 --- a/avahi-common/strlst-test.c +++ b/avahi-common/strlst-test.c @@ -69,7 +69,7 @@ int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { printf("\n"); - b = avahi_string_list_parse(data, size); + assert(avahi_string_list_parse(data, size, &b) == 0); assert(avahi_string_list_equal(a, b)); @@ -119,7 +119,7 @@ int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { assert(size == 1); assert(size == n); - a = avahi_string_list_parse(data, size); + assert(avahi_string_list_parse(data, size, &a) == 0); assert(!a); return 0; diff --git a/avahi-common/strlst.c b/avahi-common/strlst.c index 04941b4..4b96112 100644 --- a/avahi-common/strlst.c +++ b/avahi-common/strlst.c @@ -68,29 +68,45 @@ AvahiStringList *avahi_string_list_add(AvahiStringList *l, const char *text) { return avahi_string_list_add_arbitrary(l, (const uint8_t*) text, strlen(text)); } -AvahiStringList *avahi_string_list_parse(const void* data, size_t size) { - AvahiStringList *r = NULL; +int avahi_string_list_parse(const void* data, size_t size, AvahiStringList **ret) { const uint8_t *c; + AvahiStringList *r; assert(data); + assert(ret); + + r = NULL; c = data; - for (;;) { + while (size > 0) { size_t k; - if (size < 1) - break; - k = *(c++); + size--; - if (k > 0) /* Ignore empty strings */ - r = avahi_string_list_add_arbitrary(r, c, k); - c += k; + if (k > size) + goto fail; /* Overflow */ + + if (k > 0) { /* Ignore empty strings */ + AvahiStringList *n; - size -= 1 + k; + if (!(n = avahi_string_list_add_arbitrary(r, c, k))) + goto fail; /* OOM */ + + r = n; + } + + c += k; + size -= k; } - return r; + *ret = r; + + return 0; + +fail: + avahi_string_list_free(*ret); + return -1; } void avahi_string_list_free(AvahiStringList *l) { diff --git a/avahi-common/strlst.h b/avahi-common/strlst.h index 1e69367..26708a5 100644 --- a/avahi-common/strlst.h +++ b/avahi-common/strlst.h @@ -102,7 +102,7 @@ char* avahi_string_list_to_string(AvahiStringList *l); size_t avahi_string_list_serialize(AvahiStringList *l, void * data, size_t size); /** Inverse of avahi_string_list_serialize() */ -AvahiStringList *avahi_string_list_parse(const void *data, size_t size); +int avahi_string_list_parse(const void *data, size_t size, AvahiStringList **ret); /** Compare to string lists */ int avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b); -- cgit