Merge pull request #809 from micmac1/fs-backport-22.03
[feed/telephony.git] / libs / pjproject / patches / 0200-potential-buffer-overflow-in-pjlib-scanner-and-pjmedia.patch
1 From c4d34984ec92b3d5252a7d5cddd85a1d3a8001ae Mon Sep 17 00:00:00 2001
2 From: sauwming <ming@teluu.com>
3 Date: Mon, 3 Oct 2022 08:07:22 +0800
4 Subject: [PATCH] Merge pull request from GHSA-fq45-m3f7-3mhj
5
6 * Initial patch
7
8 * Use 'pj_scan_is_eof(scanner)'
9
10 Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
11
12 * Use 'pj_scan_is_eof(scanner)'
13
14 Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
15
16 * Use 'pj_scan_is_eof(scanner)'
17
18 Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
19
20 * Use `!pj_scan_is_eof` instead of manually checking `scanner->curptr < scanner->end`
21
22 Co-authored-by: Maksim Mukosey <mmukosey@gmail.com>
23
24 * Update pjlib-util/src/pjlib-util/scanner.c
25
26 Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
27
28 * Update pjlib-util/src/pjlib-util/scanner.c
29
30 Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
31
32 * Update pjlib-util/src/pjlib-util/scanner.c
33
34 Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
35
36 * Revert '>=' back to '>' in pj_scan_stricmp_alnum()
37
38 * Fix error compiles.
39
40 Co-authored-by: Nanang Izzuddin <nanang@teluu.com>
41 Co-authored-by: Aaron Lichtman <aaronlichtman@gmail.com>
42 Co-authored-by: Maksim Mukosey <mmukosey@gmail.com>
43 ---
44 pjlib-util/src/pjlib-util/scanner.c | 41 +++++++++++++++++++----------
45 pjmedia/src/pjmedia/rtp.c | 11 +++++---
46 pjmedia/src/pjmedia/sdp.c | 24 ++++++++++-------
47 3 files changed, 48 insertions(+), 28 deletions(-)
48
49 --- a/pjlib-util/src/pjlib-util/scanner.c
50 +++ b/pjlib-util/src/pjlib-util/scanner.c
51 @@ -195,7 +195,13 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj
52
53 PJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner )
54 {
55 - char *s = pj_memchr(scanner->curptr, '\n', scanner->end - scanner->curptr);
56 + char *s;
57 +
58 + if (pj_scan_is_eof(scanner)) {
59 + return;
60 + }
61 +
62 + s = pj_memchr(scanner->curptr, '\n', scanner->end - scanner->curptr);
63 if (!s) {
64 scanner->curptr = scanner->end;
65 } else {
66 @@ -264,8 +270,7 @@ PJ_DEF(void) pj_scan_get( pj_scanner *sc
67
68 pj_assert(pj_cis_match(spec,0)==0);
69
70 - /* EOF is detected implicitly */
71 - if (!pj_cis_match(spec, *s)) {
72 + if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s)) {
73 pj_scan_syntax_err(scanner);
74 return;
75 }
76 @@ -299,8 +304,7 @@ PJ_DEF(void) pj_scan_get_unescape( pj_sc
77 /* Must not match character '%' */
78 pj_assert(pj_cis_match(spec,'%')==0);
79
80 - /* EOF is detected implicitly */
81 - if (!pj_cis_match(spec, *s) && *s != '%') {
82 + if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s) && *s != '%') {
83 pj_scan_syntax_err(scanner);
84 return;
85 }
86 @@ -436,7 +440,9 @@ PJ_DEF(void) pj_scan_get_n( pj_scanner *
87
88 scanner->curptr += N;
89
90 - if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
91 + if (!pj_scan_is_eof(scanner) &&
92 + PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws)
93 + {
94 pj_scan_skip_whitespace(scanner);
95 }
96 }
97 @@ -467,15 +473,16 @@ PJ_DEF(int) pj_scan_get_char( pj_scanner
98
99 PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )
100 {
101 - if (!PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {
102 + if (pj_scan_is_eof(scanner) || !PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {
103 pj_scan_syntax_err(scanner);
104 return;
105 }
106
107 + /* We have checked scanner->curptr validity above */
108 if (*scanner->curptr == '\r') {
109 ++scanner->curptr;
110 }
111 - if (*scanner->curptr == '\n') {
112 + if (!pj_scan_is_eof(scanner) && *scanner->curptr == '\n') {
113 ++scanner->curptr;
114 }
115
116 @@ -520,7 +527,9 @@ PJ_DEF(void) pj_scan_get_until( pj_scann
117
118 scanner->curptr = s;
119
120 - if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
121 + if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) &&
122 + scanner->skip_ws)
123 + {
124 pj_scan_skip_whitespace(scanner);
125 }
126 }
127 @@ -544,7 +553,9 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_sc
128
129 scanner->curptr = s;
130
131 - if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
132 + if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) &&
133 + scanner->skip_ws)
134 + {
135 pj_scan_skip_whitespace(scanner);
136 }
137 }
138 @@ -570,7 +581,9 @@ PJ_DEF(void) pj_scan_get_until_chr( pj_s
139
140 scanner->curptr = s;
141
142 - if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
143 + if (!pj_scan_is_eof(scanner) && PJ_SCAN_IS_PROBABLY_SPACE(*s) &&
144 + scanner->skip_ws)
145 + {
146 pj_scan_skip_whitespace(scanner);
147 }
148 }
149 @@ -585,7 +598,9 @@ PJ_DEF(void) pj_scan_advance_n( pj_scann
150
151 scanner->curptr += N;
152
153 - if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) {
154 + if (!pj_scan_is_eof(scanner) &&
155 + PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws)
156 + {
157 pj_scan_skip_whitespace(scanner);
158 }
159 }
160 @@ -636,5 +651,3 @@ PJ_DEF(void) pj_scan_restore_state( pj_s
161 scanner->line = state->line;
162 scanner->start_line = state->start_line;
163 }
164 -
165 -
166 --- a/pjmedia/src/pjmedia/rtp.c
167 +++ b/pjmedia/src/pjmedia/rtp.c
168 @@ -188,6 +188,11 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_r
169 /* Payload is located right after header plus CSRC */
170 offset = sizeof(pjmedia_rtp_hdr) + ((*hdr)->cc * sizeof(pj_uint32_t));
171
172 + /* Check that offset is less than packet size */
173 + if (offset >= pkt_len) {
174 + return PJMEDIA_RTP_EINLEN;
175 + }
176 +
177 /* Decode RTP extension. */
178 if ((*hdr)->x) {
179 if (offset + sizeof (pjmedia_rtp_ext_hdr) > (unsigned)pkt_len)
180 @@ -202,8 +207,8 @@ PJ_DEF(pj_status_t) pjmedia_rtp_decode_r
181 dec_hdr->ext_len = 0;
182 }
183
184 - /* Check that offset is less than packet size */
185 - if (offset > pkt_len)
186 + /* Check again that offset is still less than packet size */
187 + if (offset >= pkt_len)
188 return PJMEDIA_RTP_EINLEN;
189
190 /* Find and set payload. */
191 @@ -393,5 +398,3 @@ void pjmedia_rtp_seq_update( pjmedia_rtp
192 seq_status->status.value = st.status.value;
193 }
194 }
195 -
196 -
197 --- a/pjmedia/src/pjmedia/sdp.c
198 +++ b/pjmedia/src/pjmedia/sdp.c
199 @@ -983,13 +983,13 @@ static void parse_version(pj_scanner *sc
200 ctx->last_error = PJMEDIA_SDP_EINVER;
201
202 /* check equal sign */
203 - if (*(scanner->curptr+1) != '=') {
204 + if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
205 on_scanner_error(scanner);
206 return;
207 }
208
209 /* check version is 0 */
210 - if (*(scanner->curptr+2) != '0') {
211 + if (scanner->curptr+2 >= scanner->end || *(scanner->curptr+2) != '0') {
212 on_scanner_error(scanner);
213 return;
214 }
215 @@ -1006,7 +1006,7 @@ static void parse_origin(pj_scanner *sca
216 ctx->last_error = PJMEDIA_SDP_EINORIGIN;
217
218 /* check equal sign */
219 - if (*(scanner->curptr+1) != '=') {
220 + if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
221 on_scanner_error(scanner);
222 return;
223 }
224 @@ -1052,7 +1052,7 @@ static void parse_time(pj_scanner *scann
225 ctx->last_error = PJMEDIA_SDP_EINTIME;
226
227 /* check equal sign */
228 - if (*(scanner->curptr+1) != '=') {
229 + if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
230 on_scanner_error(scanner);
231 return;
232 }
233 @@ -1080,7 +1080,7 @@ static void parse_generic_line(pj_scanne
234 ctx->last_error = PJMEDIA_SDP_EINSDP;
235
236 /* check equal sign */
237 - if (*(scanner->curptr+1) != '=') {
238 + if ((scanner->curptr+1 >= scanner->end) || *(scanner->curptr+1) != '=') {
239 on_scanner_error(scanner);
240 return;
241 }
242 @@ -1149,7 +1149,7 @@ static void parse_media(pj_scanner *scan
243 ctx->last_error = PJMEDIA_SDP_EINMEDIA;
244
245 /* check the equal sign */
246 - if (*(scanner->curptr+1) != '=') {
247 + if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
248 on_scanner_error(scanner);
249 return;
250 }
251 @@ -1164,6 +1164,10 @@ static void parse_media(pj_scanner *scan
252 /* port */
253 pj_scan_get(scanner, &cs_token, &str);
254 med->desc.port = (unsigned short)pj_strtoul(&str);
255 + if (pj_scan_is_eof(scanner)) {
256 + on_scanner_error(scanner);
257 + return;
258 + }
259 if (*scanner->curptr == '/') {
260 /* port count */
261 pj_scan_get_char(scanner);
262 @@ -1175,7 +1179,7 @@ static void parse_media(pj_scanner *scan
263 }
264
265 if (pj_scan_get_char(scanner) != ' ') {
266 - PJ_THROW(SYNTAX_ERROR);
267 + on_scanner_error(scanner);
268 }
269
270 /* transport */
271 @@ -1183,7 +1187,7 @@ static void parse_media(pj_scanner *scan
272
273 /* format list */
274 med->desc.fmt_count = 0;
275 - while (*scanner->curptr == ' ') {
276 + while (scanner->curptr < scanner->end && *scanner->curptr == ' ') {
277 pj_str_t fmt;
278
279 pj_scan_get_char(scanner);
280 @@ -1223,7 +1227,7 @@ static pjmedia_sdp_attr *parse_attr( pj_
281 attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);
282
283 /* check equal sign */
284 - if (*(scanner->curptr+1) != '=') {
285 + if (scanner->curptr+1 >= scanner->end || *(scanner->curptr+1) != '=') {
286 on_scanner_error(scanner);
287 return NULL;
288 }
289 @@ -1242,7 +1246,7 @@ static pjmedia_sdp_attr *parse_attr( pj_
290 pj_scan_get_char(scanner);
291
292 /* get value */
293 - if (*scanner->curptr != '\r' && *scanner->curptr != '\n') {
294 + if (!pj_scan_is_eof(scanner) && *scanner->curptr != '\r' && *scanner->curptr != '\n') {
295 pj_scan_get_until_chr(scanner, "\r\n", &attr->value);
296 } else {
297 attr->value.ptr = NULL;