aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/rose/rose_subr.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index 1734abba26a2..174d51c9ce37 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -290,10 +290,15 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *
290 facilities->source_ndigis = 0; 290 facilities->source_ndigis = 0;
291 facilities->dest_ndigis = 0; 291 facilities->dest_ndigis = 0;
292 for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) { 292 for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) {
293 if (pt[6] & AX25_HBIT) 293 if (pt[6] & AX25_HBIT) {
294 if (facilities->dest_ndigis >= ROSE_MAX_DIGIS)
295 return -1;
294 memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN); 296 memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN);
295 else 297 } else {
298 if (facilities->source_ndigis >= ROSE_MAX_DIGIS)
299 return -1;
296 memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN); 300 memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN);
301 }
297 } 302 }
298 } 303 }
299 p += l + 2; 304 p += l + 2;
@@ -333,6 +338,11 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
333 338
334 case 0xC0: 339 case 0xC0:
335 l = p[1]; 340 l = p[1];
341
342 /* Prevent overflows*/
343 if (l < 10 || l > 20)
344 return -1;
345
336 if (*p == FAC_CCITT_DEST_NSAP) { 346 if (*p == FAC_CCITT_DEST_NSAP) {
337 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); 347 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
338 memcpy(callsign, p + 12, l - 10); 348 memcpy(callsign, p + 12, l - 10);
@@ -373,12 +383,16 @@ int rose_parse_facilities(unsigned char *p,
373 switch (*p) { 383 switch (*p) {
374 case FAC_NATIONAL: /* National */ 384 case FAC_NATIONAL: /* National */
375 len = rose_parse_national(p + 1, facilities, facilities_len - 1); 385 len = rose_parse_national(p + 1, facilities, facilities_len - 1);
386 if (len < 0)
387 return 0;
376 facilities_len -= len + 1; 388 facilities_len -= len + 1;
377 p += len + 1; 389 p += len + 1;
378 break; 390 break;
379 391
380 case FAC_CCITT: /* CCITT */ 392 case FAC_CCITT: /* CCITT */
381 len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); 393 len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1);
394 if (len < 0)
395 return 0;
382 facilities_len -= len + 1; 396 facilities_len -= len + 1;
383 p += len + 1; 397 p += len + 1;
384 break; 398 break;