diff options
Diffstat (limited to 'net/x25')
-rw-r--r-- | net/x25/af_x25.c | 48 |
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(); | 1474 | out_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(); | 1509 | out_dtefac_release: |
1510 | release_sock(sk); | ||
1509 | break; | 1511 | break; |
1510 | } | 1512 | } |
1511 | 1513 | ||