From ed9005593040d652650925b4bccce7638ace56ba Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Thu, 4 Nov 2021 16:28:31 +0100 Subject: [PATCH] Grow buffer as needed when generating SDPs (fixes #2791, see #2793) --- janus.h | 2 -- sdp-utils.c | 44 ++++++++++++++++++++++++++++---------------- utils.c | 17 +++++++---------- utils.h | 14 +++++++------- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/janus.h b/janus.h index e86a72f2b3..fe42642b21 100644 --- a/janus.h +++ b/janus.h @@ -37,8 +37,6 @@ #include "plugins/plugin.h" -#define JANUS_BUFSIZE 8192 - /*! \brief Helper to address requests and their sources (e.g., a specific HTTP connection, websocket, RabbitMQ or others) */ typedef struct janus_request janus_request; diff --git a/sdp-utils.c b/sdp-utils.c index f83618cb5f..d01ce85894 100644 --- a/sdp-utils.c +++ b/sdp-utils.c @@ -910,27 +910,28 @@ char *janus_sdp_write(janus_sdp *imported) { if(!imported) return NULL; janus_refcount_increase(&imported->ref); - char *sdp = g_malloc(JANUS_BUFSIZE), buffer[512]; + char *sdp = g_malloc(1024), mline[JANUS_BUFSIZE], buffer[512]; *sdp = '\0'; + size_t sdplen = 1024, mlen = sizeof(mline); /* v= */ g_snprintf(buffer, sizeof(buffer), "v=%d\r\n", imported->version); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(sdp, buffer, sdplen); /* o= */ g_snprintf(buffer, sizeof(buffer), "o=%s %"SCNu64" %"SCNu64" IN %s %s\r\n", imported->o_name, imported->o_sessid, imported->o_version, imported->o_ipv4 ? "IP4" : "IP6", imported->o_addr); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(sdp, buffer, sdplen); /* s= */ g_snprintf(buffer, sizeof(buffer), "s=%s\r\n", imported->s_name); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(sdp, buffer, sdplen); /* t= */ g_snprintf(buffer, sizeof(buffer), "t=%"SCNu64" %"SCNu64"\r\n", imported->t_start, imported->t_stop); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(sdp, buffer, sdplen); /* c= */ if(imported->c_addr != NULL) { g_snprintf(buffer, sizeof(buffer), "c=IN %s %s\r\n", imported->c_ipv4 ? "IP4" : "IP6", imported->c_addr); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(sdp, buffer, sdplen); } /* a= */ GList *temp = imported->attributes; @@ -941,15 +942,16 @@ char *janus_sdp_write(janus_sdp *imported) { } else { g_snprintf(buffer, sizeof(buffer), "a=%s\r\n", a->name); } - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(sdp, buffer, sdplen); temp = temp->next; } /* m= */ temp = imported->m_lines; while(temp) { + mline[0] = '\0'; janus_sdp_mline *m = (janus_sdp_mline *)temp->data; g_snprintf(buffer, sizeof(buffer), "m=%s %d %s", m->type_str, m->port, m->proto); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(mline, buffer, mlen); if(m->port == 0 && m->type != JANUS_SDP_APPLICATION) { /* Remove all payload types/formats if we're rejecting the media */ g_list_free_full(m->fmts, (GDestroyNotify)g_free); @@ -957,14 +959,14 @@ char *janus_sdp_write(janus_sdp *imported) { g_list_free(m->ptypes); m->ptypes = NULL; m->ptypes = g_list_append(m->ptypes, GINT_TO_POINTER(0)); - janus_strlcat(sdp, " 0", JANUS_BUFSIZE); + janus_strlcat(mline, " 0", mlen); } else { if(m->proto != NULL && strstr(m->proto, "RTP") != NULL) { /* RTP profile, use payload types */ GList *ptypes = m->ptypes; while(ptypes) { g_snprintf(buffer, sizeof(buffer), " %d", GPOINTER_TO_INT(ptypes->data)); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(mline, buffer, mlen); ptypes = ptypes->next; } } else { @@ -972,30 +974,30 @@ char *janus_sdp_write(janus_sdp *imported) { GList *fmts = m->fmts; while(fmts) { g_snprintf(buffer, sizeof(buffer), " %s", (char *)(fmts->data)); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(mline, buffer, mlen); fmts = fmts->next; } } } - janus_strlcat(sdp, "\r\n", JANUS_BUFSIZE); + janus_strlcat(mline, "\r\n", mlen); /* c= */ if(m->c_addr != NULL) { g_snprintf(buffer, sizeof(buffer), "c=IN %s %s\r\n", m->c_ipv4 ? "IP4" : "IP6", m->c_addr); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(mline, buffer, mlen); } if(m->port > 0) { /* b= */ if(m->b_name != NULL) { g_snprintf(buffer, sizeof(buffer), "b=%s:%"SCNu32"\r\n", m->b_name, m->b_value); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(mline, buffer, mlen); } } /* a= (note that we don't format the direction if it's JANUS_SDP_DEFAULT) */ const char *direction = m->direction != JANUS_SDP_DEFAULT ? janus_sdp_mdirection_str(m->direction) : NULL; if(direction != NULL) { g_snprintf(buffer, sizeof(buffer), "a=%s\r\n", direction); - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(mline, buffer, mlen); } GList *temp2 = m->attributes; while(temp2) { @@ -1010,9 +1012,19 @@ char *janus_sdp_write(janus_sdp *imported) { } else { g_snprintf(buffer, sizeof(buffer), "a=%s\r\n", a->name); } - janus_strlcat(sdp, buffer, JANUS_BUFSIZE); + janus_strlcat(mline, buffer, mlen); temp2 = temp2->next; } + /* Append the generated m-line to the SDP */ + size_t cur_sdplen = strlen(sdp); + size_t mlinelen = strlen(mline); + if(cur_sdplen + mlinelen + 1 > sdplen) { + /* Increase the SDP buffer first */ + sdplen = cur_sdplen + mlinelen + 1; + sdp = g_realloc(sdp, sdplen); + } + janus_strlcat(sdp, mline, sdplen); + /* Move on */ temp = temp->next; } janus_refcount_decrease(&imported->ref); diff --git a/utils.c b/utils.c index 8f77a80f16..1316dd5263 100644 --- a/utils.c +++ b/utils.c @@ -272,6 +272,13 @@ char *janus_string_replace(char *message, const char *old_string, const char *ne } } +size_t janus_strlcat(char *dest, const char *src, size_t dest_size) { + size_t ret = g_strlcat(dest, src, dest_size); + if(ret >= dest_size) + JANUS_LOG(LOG_ERR, "janus_strlcat: truncation occurred, %lu >= %lu\n", ret, dest_size); + return ret; +} + int janus_mkdir(const char *dir, mode_t mode) { char tmp[256]; char *p = NULL; @@ -1217,13 +1224,3 @@ size_t janus_gzip_compress(int compression, char *text, size_t tlen, char *compr return zs.total_out; } #endif - - -gsize janus_strlcat(gchar *dest, const gchar *src, gsize dest_size) { - gsize ret = g_strlcat(dest, src, dest_size); - if (ret >= dest_size) { - JANUS_LOG(LOG_ERR, "janus_strlcat: truncation occurred, %lu >= %lu\n", ret, dest_size); - } - - return ret; -} diff --git a/utils.h b/utils.h index 17416a67d8..5325eee0fa 100644 --- a/utils.h +++ b/utils.h @@ -49,6 +49,13 @@ gint64 janus_get_real_time(void); * @returns A pointer to the updated text string (re-allocated or just updated) */ char *janus_string_replace(char *message, const char *old_string, const char *new_string) G_GNUC_WARN_UNUSED_RESULT; +/*! \brief Helper method to concatenate strings and log an error if truncation occured + * @param[in] dest destination buffer, already containing one nul-terminated string + * @param[in] src source buffer + * @param[in] dest_size length of dest buffer in bytes (not length of existing string inside dest) + * @returns size of attempted result, if retval >= dest_size, truncation occurred (and an error will be logged). */ +size_t janus_strlcat(char *dest, const char *src, size_t dest_size); + /*! \brief Helper to parse yes/no|true/false configuration values * @param value The configuration value to parse * @returns true if the value contains a "yes", "YES", "true", TRUE", "1", false otherwise */ @@ -377,13 +384,6 @@ int janus_vp9_parse_svc(char *buffer, int len, gboolean *found, janus_vp9_svc_in * @returns 0 New word value*/ guint32 janus_push_bits(guint32 word, size_t num, guint32 val); -/*! \brief Helper method to concatenate strings and log an error if truncation occured - * @param[in] dest destination buffer, already containing one nul-terminated string - * @param[in] src source buffer - * @param[in] dest_size length of dest buffer in bytes (not length of existing string inside dest) - * @returns size of attempted result, if retval >= dest_size, truncation occurred (and an error will be logged). */ -gsize janus_strlcat(gchar *dest, const gchar *src, gsize dest_size); - /*! \brief Helper method to set one byte at a memory position * @param[in] data memory data pointer * @param[in] i position in memory to change