net, compat_ioctl: handle socket ioctl abuses in tty drivers
[linux-2.6.git] / drivers / net / hamradio / mkiss.c
index 6fc0e69..fc9c578 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/jiffies.h>
+#include <linux/compat.h>
 
 #include <net/ax25.h>
 
@@ -258,7 +259,7 @@ static void ax_bump(struct mkiss *ax)
                        }
                        if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
                                printk(KERN_INFO
-                                      "mkiss: %s: Switchting to crc-smack\n",
+                                      "mkiss: %s: Switching to crc-smack\n",
                                       ax->dev->name);
                                ax->crcmode = CRC_MODE_SMACK;
                        }
@@ -272,7 +273,7 @@ static void ax_bump(struct mkiss *ax)
                        }
                        if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
                                printk(KERN_INFO
-                                      "mkiss: %s: Switchting to crc-flexnet\n",
+                                      "mkiss: %s: Switching to crc-flexnet\n",
                                       ax->dev->name);
                                ax->crcmode = CRC_MODE_FLEX;
                        }
@@ -525,13 +526,13 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
 }
 
 /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
-static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct mkiss *ax = netdev_priv(dev);
 
        if (!netif_running(dev))  {
                printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        if (netif_queue_stopped(dev)) {
@@ -541,7 +542,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
                 */
                if (time_before(jiffies, dev->trans_start + 20 * HZ)) {
                        /* 20 sec timeout not reached */
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
 
                printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
@@ -560,7 +561,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
                kfree_skb(skb);
        }
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 static int ax_open_dev(struct net_device *dev)
@@ -667,19 +668,23 @@ static const struct header_ops ax_header_ops = {
        .rebuild   = ax_rebuild_header,
 };
 
+static const struct net_device_ops ax_netdev_ops = {
+       .ndo_open            = ax_open_dev,
+       .ndo_stop            = ax_close,
+       .ndo_start_xmit      = ax_xmit,
+       .ndo_set_mac_address = ax_set_mac_address,
+};
+
 static void ax_setup(struct net_device *dev)
 {
        /* Finish setting up the DEVICE info. */
        dev->mtu             = AX_MTU;
-       dev->hard_start_xmit = ax_xmit;
-       dev->open            = ax_open_dev;
-       dev->stop            = ax_close;
-       dev->set_mac_address = ax_set_mac_address;
        dev->hard_header_len = 0;
        dev->addr_len        = 0;
        dev->type            = ARPHRD_AX25;
        dev->tx_queue_len    = 10;
        dev->header_ops      = &ax_header_ops;
+       dev->netdev_ops      = &ax_netdev_ops;
 
 
        memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
@@ -894,6 +899,23 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
        return err;
 }
 
+#ifdef CONFIG_COMPAT
+static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
+       unsigned int cmd, unsigned long arg)
+{
+       switch (arg) {
+       case SIOCGIFNAME:
+       case SIOCGIFENCAP:
+       case SIOCSIFENCAP:
+       case SIOCSIFHWADDR:
+               return mkiss_ioctl(tty, file, cmd,
+                                  (unsigned long)compat_ptr(arg));
+       }
+
+       return -ENOIOCTLCMD;
+}
+#endif
+
 /*
  * Handle the 'receiver data ready' interrupt.
  * This function is called by the 'tty_io' module in the kernel when
@@ -968,13 +990,16 @@ static struct tty_ldisc_ops ax_ldisc = {
        .open           = mkiss_open,
        .close          = mkiss_close,
        .ioctl          = mkiss_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = mkiss_compat_ioctl,
+#endif
        .receive_buf    = mkiss_receive_buf,
        .write_wakeup   = mkiss_write_wakeup
 };
 
-static char banner[] __initdata = KERN_INFO \
+static const char banner[] __initdata = KERN_INFO \
        "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initdata = KERN_ERR \
        "mkiss: can't register line discipline (err = %d)\n";
 
 static int __init mkiss_init_driver(void)
@@ -983,8 +1008,9 @@ static int __init mkiss_init_driver(void)
 
        printk(banner);
 
-       if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)
-               printk(msg_regfail);
+       status = tty_register_ldisc(N_AX25, &ax_ldisc);
+       if (status != 0)
+               printk(msg_regfail, status);
 
        return status;
 }