vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Mon May 29 18:36:54 2017 +0300| [94ab32470fff2642269ec706a8ea42dc0d5965c1] | committer: Rémi Denis-Courmont
sap: use vlc_memstream, fix heap overflow > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=94ab32470fff2642269ec706a8ea42dc0d5965c1 --- src/stream_output/sap.c | 78 +++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/src/stream_output/sap.c b/src/stream_output/sap.c index 6bac144a27..ee5312eb7d 100644 --- a/src/stream_output/sap.c +++ b/src/stream_output/sap.c @@ -36,6 +36,7 @@ #include <vlc_sout.h> #include <vlc_network.h> +#include <vlc_memstream.h> #include "stream_output.h" #include "libvlc.h" @@ -47,8 +48,8 @@ struct session_descriptor_t { struct session_descriptor_t *next; - size_t length; - uint8_t data[]; + size_t length; + char *data; }; /* A SAP announce address. For each of these, we run the @@ -298,43 +299,26 @@ sout_AnnounceRegisterSDP (vlc_object_t *obj, const char *sdp, vlc_mutex_lock (&sap_addr->lock); vlc_mutex_unlock (&sap_mutex); - size_t length = 20; - switch (sap_addr->orig.ss_family) - { -#ifdef AF_INET6 - case AF_INET6: - length += 16; - break; -#endif - case AF_INET: - length += 4; - break; - default: - vlc_assert_unreachable (); - } - - /* XXX: Check for dupes */ - length += strlen (sdp); - - session_descriptor_t *session = malloc (sizeof (*session) + length); + session_descriptor_t *session = malloc(sizeof (*session)); if (unlikely(session == NULL)) - { - vlc_mutex_unlock (&sap_addr->lock); - return NULL; /* NOTE: we should destroy the thread if left unused */ - } + goto out; /* NOTE: we should destroy the thread if left unused */ + session->next = sap_addr->first; - sap_addr->first = session; - session->length = length; /* Build the SAP Headers */ - uint8_t *buf = session->data; + struct vlc_memstream stream; + vlc_memstream_open(&stream); /* SAPv1, not encrypted, not compressed */ - buf[0] = 0x20; - buf[1] = 0x00; /* No authentication length */ - SetWBE(buf + 2, mdate()); /* ID hash */ + uint8_t flags = 0x20; +#ifdef AF_INET6 + if (sap_addr->orig.ss_family == AF_INET6) + flags |= 0x10; +#endif + vlc_memstream_putc(&stream, flags); + vlc_memstream_putc(&stream, 0x00); /* No authentication length */ + vlc_memstream_write(&stream, &(uint16_t){ mdate() }, 2); /* ID hash */ - size_t offset = 4; switch (sap_addr->orig.ss_family) { #ifdef AF_INET6 @@ -342,9 +326,7 @@ sout_AnnounceRegisterSDP (vlc_object_t *obj, const char *sdp, { const struct in6_addr *a6 = &((const struct sockaddr_in6 *)&sap_addr->orig)->sin6_addr; - memcpy (buf + offset, a6, 16); - buf[0] |= 0x10; /* IPv6 flag */ - offset += 16; + vlc_memstream_write(&stream, &a6, 16); break; } #endif @@ -352,21 +334,32 @@ sout_AnnounceRegisterSDP (vlc_object_t *obj, const char *sdp, { const struct in_addr *a4 = &((const struct sockaddr_in *)&sap_addr->orig)->sin_addr; - memcpy (buf + offset, a4, 4); - offset += 4; + vlc_memstream_write(&stream, &a4, 4); break; } - + default: + vlc_assert_unreachable (); } - memcpy (buf + offset, "application/sdp", 16); - offset += 16; + vlc_memstream_puts(&stream, "application/sdp"); + vlc_memstream_putc(&stream, '\0'); /* Build the final message */ - strcpy((char *)buf + offset, sdp); + vlc_memstream_puts(&stream, sdp); + + if (vlc_memstream_close(&stream)) + { + free(session); + session = NULL; + goto out; + } + session->data = stream.ptr; + session->length = stream.length; + sap_addr->first = session; sap_addr->session_count++; vlc_cond_signal (&sap_addr->wait); +out: vlc_mutex_unlock (&sap_addr->lock); return session; } @@ -424,5 +417,6 @@ found: vlc_mutex_unlock (&addr->lock); } - free (session); + free(session->data); + free(session); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
