aboutsummaryrefslogtreecommitdiffstats
path: root/net/ax25/af_ax25.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2011-11-24 01:12:59 -0500
committerDavid S. Miller <davem@davemloft.net>2011-11-29 00:23:12 -0500
commitbe639ac6901a082894771f55c8047d5772de5c27 (patch)
tree3c2b8e72ba8f5625d338c2104f936eef41b79175 /net/ax25/af_ax25.c
parent3b1588593097b7d71f44c4b7b435bf28924316e0 (diff)
NET: AX.25: Check ioctl arguments to avoid overflows further down the road.
Very large, nonsenical arguments or use in very extreme conditions could result in integer overflows. Check ioctls arguments to avoid such overflows and return -EINVAL for too large arguments. To allow the use of AX.25 for even the most extreme setup (think packet radio to the Phase 5E mars probe) we make no further attempt to clamp the argument range. Originally reported by Fan Long <longfancn@gmail.com> and a first patch was sent by Xi Wang <xi.wang@gmail.com>. Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Cc: Xi Wang <xi.wang@gmail.com> Cc: Joerg Reuter <jreuter@yaina.de> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Thomas Osterried <thomas@osterried.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ax25/af_ax25.c')
-rw-r--r--net/ax25/af_ax25.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index e7c69f4619ec..b863c1877c80 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -402,14 +402,14 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
402 break; 402 break;
403 403
404 case AX25_T1: 404 case AX25_T1:
405 if (ax25_ctl.arg < 1) 405 if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
406 goto einval_put; 406 goto einval_put;
407 ax25->rtt = (ax25_ctl.arg * HZ) / 2; 407 ax25->rtt = (ax25_ctl.arg * HZ) / 2;
408 ax25->t1 = ax25_ctl.arg * HZ; 408 ax25->t1 = ax25_ctl.arg * HZ;
409 break; 409 break;
410 410
411 case AX25_T2: 411 case AX25_T2:
412 if (ax25_ctl.arg < 1) 412 if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)
413 goto einval_put; 413 goto einval_put;
414 ax25->t2 = ax25_ctl.arg * HZ; 414 ax25->t2 = ax25_ctl.arg * HZ;
415 break; 415 break;
@@ -422,10 +422,15 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
422 break; 422 break;
423 423
424 case AX25_T3: 424 case AX25_T3:
425 if (ax25_ctl.arg > ULONG_MAX / HZ)
426 goto einval_put;
425 ax25->t3 = ax25_ctl.arg * HZ; 427 ax25->t3 = ax25_ctl.arg * HZ;
426 break; 428 break;
427 429
428 case AX25_IDLE: 430 case AX25_IDLE:
431 if (ax25_ctl.arg > ULONG_MAX / (60 * HZ))
432 goto einval_put;
433
429 ax25->idle = ax25_ctl.arg * 60 * HZ; 434 ax25->idle = ax25_ctl.arg * 60 * HZ;
430 break; 435 break;
431 436
@@ -571,7 +576,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
571 break; 576 break;
572 577
573 case AX25_T1: 578 case AX25_T1:
574 if (opt < 1) { 579 if (opt < 1 || opt > ULONG_MAX / HZ) {
575 res = -EINVAL; 580 res = -EINVAL;
576 break; 581 break;
577 } 582 }
@@ -580,7 +585,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
580 break; 585 break;
581 586
582 case AX25_T2: 587 case AX25_T2:
583 if (opt < 1) { 588 if (opt < 1 || opt > ULONG_MAX / HZ) {
584 res = -EINVAL; 589 res = -EINVAL;
585 break; 590 break;
586 } 591 }
@@ -596,7 +601,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
596 break; 601 break;
597 602
598 case AX25_T3: 603 case AX25_T3:
599 if (opt < 1) { 604 if (opt < 1 || opt > ULONG_MAX / HZ) {
600 res = -EINVAL; 605 res = -EINVAL;
601 break; 606 break;
602 } 607 }
@@ -604,7 +609,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
604 break; 609 break;
605 610
606 case AX25_IDLE: 611 case AX25_IDLE:
607 if (opt < 0) { 612 if (opt < 0 || opt > ULONG_MAX / (60 * HZ)) {
608 res = -EINVAL; 613 res = -EINVAL;
609 break; 614 break;
610 } 615 }