diff options
author | Lennart Poettering <lennart@poettering.net> | 2005-10-27 14:30:46 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2005-10-27 14:30:46 +0000 |
commit | 20011324500a728851e4888c890a756ecf71394b (patch) | |
tree | 9dc37356855fa1b1c009aa978158fac9c85f2d16 /avahi-common | |
parent | cf5ee4f9a5c3625a3d13b92603d1035f976228b0 (diff) |
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
Diffstat (limited to 'avahi-common')
-rw-r--r-- | avahi-common/strlst-test.c | 4 | ||||
-rw-r--r-- | avahi-common/strlst.c | 38 | ||||
-rw-r--r-- | avahi-common/strlst.h | 2 |
3 files changed, 30 insertions, 14 deletions
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); |