aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/x25/af_x25.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 45be72c3f940..2518efae8ec9 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1424,34 +1424,34 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1424 rc = x25_subscr_ioctl(cmd, argp); 1424 rc = x25_subscr_ioctl(cmd, argp);
1425 break; 1425 break;
1426 case SIOCX25GFACILITIES: { 1426 case SIOCX25GFACILITIES: {
1427 struct x25_facilities fac = x25->facilities; 1427 lock_sock(sk);
1428 lock_kernel(); 1428 rc = copy_to_user(argp, &x25->facilities,
1429 rc = copy_to_user(argp, &fac, 1429 sizeof(x25->facilities))
1430 sizeof(fac)) ? -EFAULT : 0; 1430 ? -EFAULT : 0;
1431 unlock_kernel(); 1431 release_sock(sk);
1432 break; 1432 break;
1433 } 1433 }
1434 1434
1435 case SIOCX25SFACILITIES: { 1435 case SIOCX25SFACILITIES: {
1436 struct x25_facilities facilities; 1436 struct x25_facilities facilities;
1437 rc = -EFAULT; 1437 rc = -EFAULT;
1438 lock_kernel();
1439 if (copy_from_user(&facilities, argp, 1438 if (copy_from_user(&facilities, argp,
1440 sizeof(facilities))) 1439 sizeof(facilities)))
1441 break; 1440 break;
1442 rc = -EINVAL; 1441 rc = -EINVAL;
1442 lock_sock(sk);
1443 if (sk->sk_state != TCP_LISTEN && 1443 if (sk->sk_state != TCP_LISTEN &&
1444 sk->sk_state != TCP_CLOSE) 1444 sk->sk_state != TCP_CLOSE)
1445 break; 1445 goto out_fac_release;
1446 if (facilities.pacsize_in < X25_PS16 || 1446 if (facilities.pacsize_in < X25_PS16 ||
1447 facilities.pacsize_in > X25_PS4096) 1447 facilities.pacsize_in > X25_PS4096)
1448 break; 1448 goto out_fac_release;
1449 if (facilities.pacsize_out < X25_PS16 || 1449 if (facilities.pacsize_out < X25_PS16 ||
1450 facilities.pacsize_out > X25_PS4096) 1450 facilities.pacsize_out > X25_PS4096)
1451 break; 1451 goto out_fac_release;
1452 if (facilities.winsize_in < 1 || 1452 if (facilities.winsize_in < 1 ||
1453 facilities.winsize_in > 127) 1453 facilities.winsize_in > 127)
1454 break; 1454 goto out_fac_release;
1455 if (facilities.throughput) { 1455 if (facilities.throughput) {
1456 int out = facilities.throughput & 0xf0; 1456 int out = facilities.throughput & 0xf0;
1457 int in = facilities.throughput & 0x0f; 1457 int in = facilities.throughput & 0x0f;
@@ -1459,27 +1459,28 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1459 facilities.throughput |= 1459 facilities.throughput |=
1460 X25_DEFAULT_THROUGHPUT << 4; 1460 X25_DEFAULT_THROUGHPUT << 4;
1461 else if (out < 0x30 || out > 0xD0) 1461 else if (out < 0x30 || out > 0xD0)
1462 break; 1462 goto out_fac_release;
1463 if (!in) 1463 if (!in)
1464 facilities.throughput |= 1464 facilities.throughput |=
1465 X25_DEFAULT_THROUGHPUT; 1465 X25_DEFAULT_THROUGHPUT;
1466 else if (in < 0x03 || in > 0x0D) 1466 else if (in < 0x03 || in > 0x0D)
1467 break; 1467 goto out_fac_release;
1468 } 1468 }
1469 if (facilities.reverse && 1469 if (facilities.reverse &&
1470 (facilities.reverse & 0x81) != 0x81) 1470 (facilities.reverse & 0x81) != 0x81)
1471 break; 1471 goto out_fac_release;
1472 x25->facilities = facilities; 1472 x25->facilities = facilities;
1473 rc = 0; 1473 rc = 0;
1474 unlock_kernel(); 1474out_fac_release:
1475 release_sock(sk);
1475 break; 1476 break;
1476 } 1477 }
1477 1478
1478 case SIOCX25GDTEFACILITIES: { 1479 case SIOCX25GDTEFACILITIES: {
1479 lock_kernel(); 1480 lock_sock(sk);
1480 rc = copy_to_user(argp, &x25->dte_facilities, 1481 rc = copy_to_user(argp, &x25->dte_facilities,
1481 sizeof(x25->dte_facilities)); 1482 sizeof(x25->dte_facilities));
1482 unlock_kernel(); 1483 release_sock(sk);
1483 if (rc) 1484 if (rc)
1484 rc = -EFAULT; 1485 rc = -EFAULT;
1485 break; 1486 break;
@@ -1488,24 +1489,25 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1488 case SIOCX25SDTEFACILITIES: { 1489 case SIOCX25SDTEFACILITIES: {
1489 struct x25_dte_facilities dtefacs; 1490 struct x25_dte_facilities dtefacs;
1490 rc = -EFAULT; 1491 rc = -EFAULT;
1491 lock_kernel();
1492 if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) 1492 if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
1493 break; 1493 break;
1494 rc = -EINVAL; 1494 rc = -EINVAL;
1495 lock_sock(sk);
1495 if (sk->sk_state != TCP_LISTEN && 1496 if (sk->sk_state != TCP_LISTEN &&
1496 sk->sk_state != TCP_CLOSE) 1497 sk->sk_state != TCP_CLOSE)
1497 break; 1498 goto out_dtefac_release;
1498 if (dtefacs.calling_len > X25_MAX_AE_LEN) 1499 if (dtefacs.calling_len > X25_MAX_AE_LEN)
1499 break; 1500 goto out_dtefac_release;
1500 if (dtefacs.calling_ae == NULL) 1501 if (dtefacs.calling_ae == NULL)
1501 break; 1502 goto out_dtefac_release;
1502 if (dtefacs.called_len > X25_MAX_AE_LEN) 1503 if (dtefacs.called_len > X25_MAX_AE_LEN)
1503 break; 1504 goto out_dtefac_release;
1504 if (dtefacs.called_ae == NULL) 1505 if (dtefacs.called_ae == NULL)
1505 break; 1506 goto out_dtefac_release;
1506 x25->dte_facilities = dtefacs; 1507 x25->dte_facilities = dtefacs;
1507 rc = 0; 1508 rc = 0;
1508 unlock_kernel(); 1509out_dtefac_release:
1510 release_sock(sk);
1509 break; 1511 break;
1510 } 1512 }
1511 1513