diff --git a/src/modules/rtp/sap.c b/src/modules/rtp/sap.c index 7fb1a3895..8614022f8 100644 --- a/src/modules/rtp/sap.c +++ b/src/modules/rtp/sap.c @@ -213,7 +213,9 @@ int pa_sap_recv(pa_sap_context *c, bool *goodbye) { if ((unsigned) size >= sizeof(MIME_TYPE) && pa_streq(e, MIME_TYPE)) { e += sizeof(MIME_TYPE); size -= (int) sizeof(MIME_TYPE); - } else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) { + } else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1) + || strcspn(e, "\r\n") != sizeof(PA_SDP_HEADER)-1) { + /* SDP header does not start with v=0[\r]\n */ pa_log_warn("Invalid SDP header."); goto fail; } diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c index e130509df..4e6a442f8 100644 --- a/src/modules/rtp/sdp.c +++ b/src/modules/rtp/sdp.c @@ -73,7 +73,7 @@ char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, u pa_assert_se(inet_ntop(af, dst, buf_dst, sizeof(buf_dst))); return pa_sprintf_malloc( - PA_SDP_HEADER + PA_SDP_HEADER "\n" "o=%s %lu 0 IN %s %s\n" "s=%s\n" "c=IN %s %s\n" @@ -130,17 +130,29 @@ pa_sdp_info *pa_sdp_parse(const char *t, pa_sdp_info *i, int is_goodbye) { i->salen = 0; i->payload = 255; - if (!pa_startswith(t, PA_SDP_HEADER)) { + if (pa_startswith(t, PA_SDP_HEADER)) { + t += sizeof(PA_SDP_HEADER) - 1; + + /* CR delimiter is optional */ + if (*t == '\r') + t++; + + /* LF delimiter is mandatory */ + if (*t == '\n') + t++; + else { + pa_log("Failed to parse SDP data: missing header record terminator LF."); + goto fail; + } + } else { pa_log("Failed to parse SDP data: invalid header."); goto fail; } - t += sizeof(PA_SDP_HEADER)-1; - while (*t) { size_t l; - l = strcspn(t, "\n"); + l = strcspn(t, "\r\n"); if (l <= 2) { pa_log("Failed to parse SDP data: line too short: >%s<.", t); @@ -240,8 +252,17 @@ pa_sdp_info *pa_sdp_parse(const char *t, pa_sdp_info *i, int is_goodbye) { t += l; + /* CR delimiter is optional */ + if (*t == '\r') + t++; + + /* LF delimiter is mandatory */ if (*t == '\n') t++; + else { + pa_log("Failed to parse SDP data: missing record terminator LF."); + goto fail; + } } if (!i->origin || (!is_goodbye && (!i->salen || i->payload > 127 || !ss_valid || port == 0))) { diff --git a/src/modules/rtp/sdp.h b/src/modules/rtp/sdp.h index 28c755a27..80ab3636e 100644 --- a/src/modules/rtp/sdp.h +++ b/src/modules/rtp/sdp.h @@ -26,7 +26,7 @@ #include -#define PA_SDP_HEADER "v=0\n" +#define PA_SDP_HEADER "v=0" typedef struct pa_sdp_info { char *origin;