[vlc-commits] sap: use vlc_memstream, fix heap overflow
Rémi Denis-Courmont
git at videolan.org
Mon May 29 17:40:33 CEST 2017
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | 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);
}
More information about the vlc-commits
mailing list