summaryrefslogtreecommitdiffstats
path: root/avahi-common
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-10-27 14:30:46 +0000
committerLennart Poettering <lennart@poettering.net>2005-10-27 14:30:46 +0000
commit20011324500a728851e4888c890a756ecf71394b (patch)
tree9dc37356855fa1b1c009aa978158fac9c85f2d16 /avahi-common
parentcf5ee4f9a5c3625a3d13b92603d1035f976228b0 (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.c4
-rw-r--r--avahi-common/strlst.c38
-rw-r--r--avahi-common/strlst.h2
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);