aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaun Pereira <spereira@tusc.com.au>2006-03-22 03:00:12 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-22 03:00:12 -0500
commit1b06e6ba25a37fe1c289049d0e0300d71ae39eff (patch)
treee119b3bf47125cb1b5a32fab531815890202d334
parentf0ac2614412e2b597e2d5bfbd3960b4f73718b41 (diff)
[X25]: ioctl conversion 32 bit user to 64 bit kernel
To allow 32 bit x25 module structures to be passed to a 64 bit kernel via ioctl using the new compat_sock_ioctl registration mechanism instead of the obsolete 'register_ioctl32_conversion into hash table' mechanism Signed-off-by: Shaun Pereira <spereira@tusc.com.au> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/x25/af_x25.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 72b6ff3299ba..a41cc0201760 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -54,7 +54,10 @@
54#include <linux/termios.h> /* For TIOCINQ/OUTQ */ 54#include <linux/termios.h> /* For TIOCINQ/OUTQ */
55#include <linux/notifier.h> 55#include <linux/notifier.h>
56#include <linux/init.h> 56#include <linux/init.h>
57#include <linux/compat.h>
58
57#include <net/x25.h> 59#include <net/x25.h>
60#include <net/compat.h>
58 61
59int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20; 62int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
60int sysctl_x25_call_request_timeout = X25_DEFAULT_T21; 63int sysctl_x25_call_request_timeout = X25_DEFAULT_T21;
@@ -69,6 +72,14 @@ static const struct proto_ops x25_proto_ops;
69 72
70static struct x25_address null_x25_address = {" "}; 73static struct x25_address null_x25_address = {" "};
71 74
75#ifdef CONFIG_COMPAT
76struct compat_x25_subscrip_struct {
77 char device[200-sizeof(compat_ulong_t)];
78 compat_ulong_t global_facil_mask;
79 compat_uint_t extended;
80};
81#endif
82
72int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, 83int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
73 struct x25_address *calling_addr) 84 struct x25_address *calling_addr)
74{ 85{
@@ -1387,6 +1398,116 @@ static struct net_proto_family x25_family_ops = {
1387 .owner = THIS_MODULE, 1398 .owner = THIS_MODULE,
1388}; 1399};
1389 1400
1401#ifdef CONFIG_COMPAT
1402static int compat_x25_subscr_ioctl(unsigned int cmd,
1403 struct compat_x25_subscrip_struct __user *x25_subscr32)
1404{
1405 struct compat_x25_subscrip_struct x25_subscr;
1406 struct x25_neigh *nb;
1407 struct net_device *dev;
1408 int rc = -EINVAL;
1409
1410 rc = -EFAULT;
1411 if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
1412 goto out;
1413
1414 rc = -EINVAL;
1415 dev = x25_dev_get(x25_subscr.device);
1416 if (dev == NULL)
1417 goto out;
1418
1419 nb = x25_get_neigh(dev);
1420 if (nb == NULL)
1421 goto out_dev_put;
1422
1423 dev_put(dev);
1424
1425 if (cmd == SIOCX25GSUBSCRIP) {
1426 x25_subscr.extended = nb->extended;
1427 x25_subscr.global_facil_mask = nb->global_facil_mask;
1428 rc = copy_to_user(x25_subscr32, &x25_subscr,
1429 sizeof(*x25_subscr32)) ? -EFAULT : 0;
1430 } else {
1431 rc = -EINVAL;
1432 if (x25_subscr.extended == 0 || x25_subscr.extended == 1) {
1433 rc = 0;
1434 nb->extended = x25_subscr.extended;
1435 nb->global_facil_mask = x25_subscr.global_facil_mask;
1436 }
1437 }
1438 x25_neigh_put(nb);
1439out:
1440 return rc;
1441out_dev_put:
1442 dev_put(dev);
1443 goto out;
1444}
1445
1446static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1447 unsigned long arg)
1448{
1449 void __user *argp = compat_ptr(arg);
1450 struct sock *sk = sock->sk;
1451
1452 int rc = -ENOIOCTLCMD;
1453
1454 switch(cmd) {
1455 case TIOCOUTQ:
1456 case TIOCINQ:
1457 rc = x25_ioctl(sock, cmd, (unsigned long)argp);
1458 break;
1459 case SIOCGSTAMP:
1460 rc = -EINVAL;
1461 if (sk)
1462 rc = compat_sock_get_timestamp(sk,
1463 (struct timeval __user*)argp);
1464 break;
1465 case SIOCGIFADDR:
1466 case SIOCSIFADDR:
1467 case SIOCGIFDSTADDR:
1468 case SIOCSIFDSTADDR:
1469 case SIOCGIFBRDADDR:
1470 case SIOCSIFBRDADDR:
1471 case SIOCGIFNETMASK:
1472 case SIOCSIFNETMASK:
1473 case SIOCGIFMETRIC:
1474 case SIOCSIFMETRIC:
1475 rc = -EINVAL;
1476 break;
1477 case SIOCADDRT:
1478 case SIOCDELRT:
1479 rc = -EPERM;
1480 if (!capable(CAP_NET_ADMIN))
1481 break;
1482 rc = x25_route_ioctl(cmd, argp);
1483 break;
1484 case SIOCX25GSUBSCRIP:
1485 rc = compat_x25_subscr_ioctl(cmd, argp);
1486 break;
1487 case SIOCX25SSUBSCRIP:
1488 rc = -EPERM;
1489 if (!capable(CAP_NET_ADMIN))
1490 break;
1491 rc = compat_x25_subscr_ioctl(cmd, argp);
1492 break;
1493 case SIOCX25GFACILITIES:
1494 case SIOCX25SFACILITIES:
1495 case SIOCX25GCALLUSERDATA:
1496 case SIOCX25SCALLUSERDATA:
1497 case SIOCX25GCAUSEDIAG:
1498 case SIOCX25SCUDMATCHLEN:
1499 case SIOCX25CALLACCPTAPPRV:
1500 case SIOCX25SENDCALLACCPT:
1501 rc = x25_ioctl(sock, cmd, (unsigned long)argp);
1502 break;
1503 default:
1504 rc = -ENOIOCTLCMD;
1505 break;
1506 }
1507 return rc;
1508}
1509#endif
1510
1390static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { 1511static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1391 .family = AF_X25, 1512 .family = AF_X25,
1392 .owner = THIS_MODULE, 1513 .owner = THIS_MODULE,
@@ -1398,6 +1519,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1398 .getname = x25_getname, 1519 .getname = x25_getname,
1399 .poll = datagram_poll, 1520 .poll = datagram_poll,
1400 .ioctl = x25_ioctl, 1521 .ioctl = x25_ioctl,
1522#ifdef CONFIG_COMPAT
1523 .compat_ioctl = compat_x25_ioctl,
1524#endif
1401 .listen = x25_listen, 1525 .listen = x25_listen,
1402 .shutdown = sock_no_shutdown, 1526 .shutdown = sock_no_shutdown,
1403 .setsockopt = x25_setsockopt, 1527 .setsockopt = x25_setsockopt,