Merge pull request #793 from micmac1/ast-18.5.1-21.02
[feed/telephony.git] / libs / pjproject / patches / 0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch
diff --git a/libs/pjproject/patches/0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch b/libs/pjproject/patches/0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch
new file mode 100644 (file)
index 0000000..ebe92b6
--- /dev/null
@@ -0,0 +1,297 @@
+From c4d34984ec92b3d5252a7d5cddd85a1d3a8001ae Mon Sep 17 00:00:00 2001
+From: sauwming <ming@teluu.com>
+Date: Mon, 3 Oct 2022 08:07:22 +0800
+Subject: [PATCH] Merge pull request from GHSA-fq45-m3f7-3mhj
+
+* Initial patch
+
+* Use 'pj_scan_is_eof(scanner)'
+
+Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
+
+* Use 'pj_scan_is_eof(scanner)'
+
+Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
+
+* Use 'pj_scan_is_eof(scanner)'
+
+Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
+
+* Use `!pj_scan_is_eof` instead of manually checking `scanner->curptr < scanner->end`
+
+Co-authored-by: Maksim Mukosey <mmukosey@gmail.com>
+
+* Update pjlib-util/src/pjlib-util/scanner.c
+
+Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
+
+* Update pjlib-util/src/pjlib-util/scanner.c
+
+Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
+
+* Update pjlib-util/src/pjlib-util/scanner.c
+
+Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
+
+* Revert '>=' back to '>' in pj_scan_stricmp_alnum()
+
+* Fix error compiles.
+
+Co-authored-by: Nanang Izzuddin <nanang@teluu.com>
+Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
+Co-authored-by: Maksim Mukosey <mmukosey@gmail.com>
+---
+ pjlib-util/src/pjlib-util/scanner.c | 41 +++++++++++++++++++----------
+ pjmedia/src/pjmedia/rtp.c           | 11 +++++---
+ pjmedia/src/pjmedia/sdp.c           | 24 ++++++++++-------
+ 3 files changed, 48 insertions(+), 28 deletions(-)
+
+--- a/pjlib-util/src/pjlib-util/scanner.c
++++ b/pjlib-util/src/pjlib-util/scanner.c
+@@ -195,7 +195,13 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj
+ PJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner )
+ {
+-    char *s = pj_memchr(scanner->curptr, '\n', scanner->end - scanner->curptr);
++    char *s;
++
++    if (pj_scan_is_eof(scanner)) {
++        return;
++    }
++
++    s = pj_memchr(scanner->curptr, '\n', scanner->end - scanner->curptr);
+     if (!s) {
+       scanner->curptr = scanner->end;
+     } else {
+@@ -264,8 +270,7 @@ PJ_DEF(void) pj_scan_get( pj_scanner *sc
+     pj_assert(pj_cis_match(spec,0)==0);
+-    /* EOF is detected implicitly */
+-    if (!pj_cis_match(spec, *s)) {
++    if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s)) {
+       pj_scan_syntax_err(scanner);
+       return;
+     }
+@@ -299,8 +304,7 @@ PJ_DEF(void) pj_scan_get_unescape( pj_sc
+     /* Must not match character '%' */
+     pj_assert(pj_cis_match(spec,'%')==0);
+-    /* EOF is detected implicitly */
+-    if (!pj_cis_match(spec, *s) && *s != '%') {
++    if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s) && *s != '%') {
+       pj_scan_syntax_err(scanner);
+       return;
+     }
+@@ -436,7 +440,9 @@ PJ_DEF(void) pj_scan_get_n( pj_scanner *
+     
+     scanner->curptr += N;
+-    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
++    if (!pj_scan_is_eof(scanner) &&
++      PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws)
++    {
+       pj_scan_skip_whitespace(scanner);
+     }
+ }
+@@ -467,15 +473,16 @@ PJ_DEF(int) pj_scan_get_char( pj_scanner
+ PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )
+ {
+-    if (!PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {
++    if (pj_scan_is_eof(scanner) || !PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {
+       pj_scan_syntax_err(scanner);
+       return;
+     }
++    /* We have checked scanner->curptr validity above */
+     if (*scanner->curptr == '\r') {
+       ++scanner->curptr;
+     }
+-    if (*scanner->curptr == '\n') {
++    if (!pj_scan_is_eof(scanner) && *scanner->curptr == '\n') {
+       ++scanner->curptr;
+     }
+@@ -520,7 +527,9 @@ PJ_DEF(void) pj_scan_get_until( pj_scann
+     scanner->curptr = s;
+-    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
++    if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) &&
++      scanner->skip_ws)
++    {
+       pj_scan_skip_whitespace(scanner);
+     }
+ }
+@@ -544,7 +553,9 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_sc
+     scanner->curptr = s;
+-    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
++    if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) &&
++      scanner->skip_ws)
++    {
+       pj_scan_skip_whitespace(scanner);
+     }
+ }
+@@ -570,7 +581,9 @@ PJ_DEF(void) pj_scan_get_until_chr( pj_s
+     scanner->curptr = s;
+-    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
++    if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) &&
++      scanner->skip_ws)
++    {
+       pj_scan_skip_whitespace(scanner);
+     }
+ }
+@@ -585,7 +598,9 @@ PJ_DEF(void) pj_scan_advance_n( pj_scann
+     scanner->curptr += N;
+-    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) {
++    if (!pj_scan_is_eof(scanner) && 
++      PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws)
++    {
+       pj_scan_skip_whitespace(scanner);
+     }
+ }
+@@ -636,5 +651,3 @@ PJ_DEF(void) pj_scan_restore_state( pj_s
+     scanner->line = state->line;
+     scanner->start_line = state->start_line;
+ }
+-
+-
+--- a/pjmedia/src/pjmedia/rtp.c
++++ b/pjmedia/src/pjmedia/rtp.c
+@@ -188,6 +188,11 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_r
+     /* Payload is located right after header plus CSRC */
+     offset = sizeof(pjmedia_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t));
++    /* Check that offset is less than packet size */
++    if (offset >= pkt_len) {
++        return PJMEDIA_RTP_EINLEN;
++    }
++
+     /* Decode RTP extension. */
+     if ((*hdr)->x) {
+         if (offset + sizeof (pjmedia_rtp_ext_hdr) > (unsigned)pkt_len)
+@@ -202,8 +207,8 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_r
+       dec_hdr->ext_len = 0;
+     }
+-    /* Check that offset is less than packet size */
+-    if (offset > pkt_len)
++    /* Check again that offset is still less than packet size */
++    if (offset >= pkt_len)
+       return PJMEDIA_RTP_EINLEN;
+     /* Find and set payload. */
+@@ -393,5 +398,3 @@ void pjmedia_rtp_seq_update( pjmedia_rtp
+       seq_status->status.value = st.status.value;
+     }
+ }
+-
+-
+--- a/pjmedia/src/pjmedia/sdp.c
++++ b/pjmedia/src/pjmedia/sdp.c
+@@ -983,13 +983,13 @@ static void parse_version(pj_scanner *sc
+     ctx->last_error = PJMEDIA_SDP_EINVER;
+     /* check equal sign */
+-    if (*(scanner->curptr+1) != '=') {
++    if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
+       on_scanner_error(scanner);
+       return;
+     }
+     /* check version is 0 */
+-    if (*(scanner->curptr+2) != '0') {
++    if (scanner->curptr+2 >= scanner->end || *(scanner->curptr+2) != '0') {
+       on_scanner_error(scanner);
+       return;
+     }
+@@ -1006,7 +1006,7 @@ static void parse_origin(pj_scanner *sca
+     ctx->last_error = PJMEDIA_SDP_EINORIGIN;
+     /* check equal sign */
+-    if (*(scanner->curptr+1) != '=') {
++    if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
+       on_scanner_error(scanner);
+       return;
+     }
+@@ -1052,7 +1052,7 @@ static void parse_time(pj_scanner *scann
+     ctx->last_error = PJMEDIA_SDP_EINTIME;
+     /* check equal sign */
+-    if (*(scanner->curptr+1) != '=') {
++    if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
+       on_scanner_error(scanner);
+       return;
+     }
+@@ -1080,7 +1080,7 @@ static void parse_generic_line(pj_scanne
+     ctx->last_error = PJMEDIA_SDP_EINSDP;
+     /* check equal sign */
+-    if (*(scanner->curptr+1) != '=') {
++    if ((scanner->curptr+1 >= scanner->end) || *(scanner->curptr+1) != '=') {
+       on_scanner_error(scanner);
+       return;
+     }
+@@ -1149,7 +1149,7 @@ static void parse_media(pj_scanner *scan
+     ctx->last_error = PJMEDIA_SDP_EINMEDIA;
+     /* check the equal sign */
+-    if (*(scanner->curptr+1) != '=') {
++    if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
+       on_scanner_error(scanner);
+       return;
+     }
+@@ -1164,6 +1164,10 @@ static void parse_media(pj_scanner *scan
+     /* port */
+     pj_scan_get(scanner, &cs_token, &str);
+     med->desc.port = (unsigned short)pj_strtoul(&str);
++    if (pj_scan_is_eof(scanner)) {
++        on_scanner_error(scanner);
++        return;
++    }
+     if (*scanner->curptr == '/') {
+       /* port count */
+       pj_scan_get_char(scanner);
+@@ -1175,7 +1179,7 @@ static void parse_media(pj_scanner *scan
+     }
+     if (pj_scan_get_char(scanner) != ' ') {
+-      PJ_THROW(SYNTAX_ERROR);
++      on_scanner_error(scanner);
+     }
+     /* transport */
+@@ -1183,7 +1187,7 @@ static void parse_media(pj_scanner *scan
+     /* format list */
+     med->desc.fmt_count = 0;
+-    while (*scanner->curptr == ' ') {
++    while (scanner->curptr < scanner->end && *scanner->curptr == ' ') {
+       pj_str_t fmt;
+       pj_scan_get_char(scanner);
+@@ -1223,7 +1227,7 @@ static pjmedia_sdp_attr *parse_attr( pj_
+     attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);
+     /* check equal sign */
+-    if (*(scanner->curptr+1) != '=') {
++    if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
+       on_scanner_error(scanner);
+       return NULL;
+     }
+@@ -1242,7 +1246,7 @@ static pjmedia_sdp_attr *parse_attr( pj_
+           pj_scan_get_char(scanner);
+       /* get value */
+-      if (*scanner->curptr != '\r' && *scanner->curptr != '\n') {
++      if (!pj_scan_is_eof(scanner) && *scanner->curptr != '\r' && *scanner->curptr != '\n') {
+           pj_scan_get_until_chr(scanner, "\r\n", &attr->value);
+       } else {
+           attr->value.ptr = NULL;