diff options
author | Arnd Bergmann <arnd@arndb.de> | 2009-11-07 01:51:16 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-07 01:52:38 -0500 |
commit | 9646e7ce3d1955478aa0573b36c151ab4b649486 (patch) | |
tree | ecef431218a43293cf0b71eec52427b20f618b02 | |
parent | 50857e2a59d8beddc6bb76137df026d67f30d5ca (diff) |
net, compat_ioctl: handle socket ioctl abuses in tty drivers
Slip and a few other drivers use the same ioctl numbers on
tty devices that are normally meant for sockets. This causes
problems with our compat_ioctl handling that tries to convert
the data structures in a different format.
Fortunately, these five drivers all use 32 bit compatible
data structures in the ioctl numbers, so we can just add
a trivial compat_ioctl conversion function to each of them.
SIOCSIFENCAP and SIOCGIFENCAP do not need to live in
fs/compat_ioctl.c after this any more, and they are not
used on any sockets.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/hamradio/6pack.c | 21 | ||||
-rw-r--r-- | drivers/net/hamradio/mkiss.c | 21 | ||||
-rw-r--r-- | drivers/net/slip.c | 25 | ||||
-rw-r--r-- | drivers/net/wan/x25_asy.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/strip.c | 17 | ||||
-rw-r--r-- | fs/compat_ioctl.c | 2 |
6 files changed, 103 insertions, 2 deletions
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index fb588301a05d..689b9bd377a5 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/ip.h> | 34 | #include <linux/ip.h> |
35 | #include <linux/tcp.h> | 35 | #include <linux/tcp.h> |
36 | #include <linux/semaphore.h> | 36 | #include <linux/semaphore.h> |
37 | #include <linux/compat.h> | ||
37 | #include <asm/atomic.h> | 38 | #include <asm/atomic.h> |
38 | 39 | ||
39 | #define SIXPACK_VERSION "Revision: 0.3.0" | 40 | #define SIXPACK_VERSION "Revision: 0.3.0" |
@@ -777,6 +778,23 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file, | |||
777 | return err; | 778 | return err; |
778 | } | 779 | } |
779 | 780 | ||
781 | #ifdef CONFIG_COMPAT | ||
782 | static long sixpack_compat_ioctl(struct tty_struct * tty, struct file * file, | ||
783 | unsigned int cmd, unsigned long arg) | ||
784 | { | ||
785 | switch (cmd) { | ||
786 | case SIOCGIFNAME: | ||
787 | case SIOCGIFENCAP: | ||
788 | case SIOCSIFENCAP: | ||
789 | case SIOCSIFHWADDR: | ||
790 | return sixpack_ioctl(tty, file, cmd, | ||
791 | (unsigned long)compat_ptr(arg)); | ||
792 | } | ||
793 | |||
794 | return -ENOIOCTLCMD; | ||
795 | } | ||
796 | #endif | ||
797 | |||
780 | static struct tty_ldisc_ops sp_ldisc = { | 798 | static struct tty_ldisc_ops sp_ldisc = { |
781 | .owner = THIS_MODULE, | 799 | .owner = THIS_MODULE, |
782 | .magic = TTY_LDISC_MAGIC, | 800 | .magic = TTY_LDISC_MAGIC, |
@@ -784,6 +802,9 @@ static struct tty_ldisc_ops sp_ldisc = { | |||
784 | .open = sixpack_open, | 802 | .open = sixpack_open, |
785 | .close = sixpack_close, | 803 | .close = sixpack_close, |
786 | .ioctl = sixpack_ioctl, | 804 | .ioctl = sixpack_ioctl, |
805 | #ifdef CONFIG_COMPAT | ||
806 | .compat_ioctl = sixpack_compat_ioctl, | ||
807 | #endif | ||
787 | .receive_buf = sixpack_receive_buf, | 808 | .receive_buf = sixpack_receive_buf, |
788 | .write_wakeup = sixpack_write_wakeup, | 809 | .write_wakeup = sixpack_write_wakeup, |
789 | }; | 810 | }; |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index db4b7f1603f6..fc9c57893f8a 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/if_arp.h> | 37 | #include <linux/if_arp.h> |
38 | #include <linux/jiffies.h> | 38 | #include <linux/jiffies.h> |
39 | #include <linux/compat.h> | ||
39 | 40 | ||
40 | #include <net/ax25.h> | 41 | #include <net/ax25.h> |
41 | 42 | ||
@@ -898,6 +899,23 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file, | |||
898 | return err; | 899 | return err; |
899 | } | 900 | } |
900 | 901 | ||
902 | #ifdef CONFIG_COMPAT | ||
903 | static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file, | ||
904 | unsigned int cmd, unsigned long arg) | ||
905 | { | ||
906 | switch (arg) { | ||
907 | case SIOCGIFNAME: | ||
908 | case SIOCGIFENCAP: | ||
909 | case SIOCSIFENCAP: | ||
910 | case SIOCSIFHWADDR: | ||
911 | return mkiss_ioctl(tty, file, cmd, | ||
912 | (unsigned long)compat_ptr(arg)); | ||
913 | } | ||
914 | |||
915 | return -ENOIOCTLCMD; | ||
916 | } | ||
917 | #endif | ||
918 | |||
901 | /* | 919 | /* |
902 | * Handle the 'receiver data ready' interrupt. | 920 | * Handle the 'receiver data ready' interrupt. |
903 | * This function is called by the 'tty_io' module in the kernel when | 921 | * This function is called by the 'tty_io' module in the kernel when |
@@ -972,6 +990,9 @@ static struct tty_ldisc_ops ax_ldisc = { | |||
972 | .open = mkiss_open, | 990 | .open = mkiss_open, |
973 | .close = mkiss_close, | 991 | .close = mkiss_close, |
974 | .ioctl = mkiss_ioctl, | 992 | .ioctl = mkiss_ioctl, |
993 | #ifdef CONFIG_COMPAT | ||
994 | .compat_ioctl = mkiss_compat_ioctl, | ||
995 | #endif | ||
975 | .receive_buf = mkiss_receive_buf, | 996 | .receive_buf = mkiss_receive_buf, |
976 | .write_wakeup = mkiss_write_wakeup | 997 | .write_wakeup = mkiss_write_wakeup |
977 | }; | 998 | }; |
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index e17c535a577e..ccfe45924fd9 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -79,6 +79,7 @@ | |||
79 | #include <linux/rtnetlink.h> | 79 | #include <linux/rtnetlink.h> |
80 | #include <linux/if_arp.h> | 80 | #include <linux/if_arp.h> |
81 | #include <linux/if_slip.h> | 81 | #include <linux/if_slip.h> |
82 | #include <linux/compat.h> | ||
82 | #include <linux/delay.h> | 83 | #include <linux/delay.h> |
83 | #include <linux/init.h> | 84 | #include <linux/init.h> |
84 | #include "slip.h" | 85 | #include "slip.h" |
@@ -1168,6 +1169,27 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, | |||
1168 | } | 1169 | } |
1169 | } | 1170 | } |
1170 | 1171 | ||
1172 | #ifdef CONFIG_COMPAT | ||
1173 | static long slip_compat_ioctl(struct tty_struct *tty, struct file *file, | ||
1174 | unsigned int cmd, unsigned long arg) | ||
1175 | { | ||
1176 | switch (cmd) { | ||
1177 | case SIOCGIFNAME: | ||
1178 | case SIOCGIFENCAP: | ||
1179 | case SIOCSIFENCAP: | ||
1180 | case SIOCSIFHWADDR: | ||
1181 | case SIOCSKEEPALIVE: | ||
1182 | case SIOCGKEEPALIVE: | ||
1183 | case SIOCSOUTFILL: | ||
1184 | case SIOCGOUTFILL: | ||
1185 | return slip_ioctl(tty, file, cmd, | ||
1186 | (unsigned long)compat_ptr(arg)); | ||
1187 | } | ||
1188 | |||
1189 | return -ENOIOCTLCMD; | ||
1190 | } | ||
1191 | #endif | ||
1192 | |||
1171 | /* VSV changes start here */ | 1193 | /* VSV changes start here */ |
1172 | #ifdef CONFIG_SLIP_SMART | 1194 | #ifdef CONFIG_SLIP_SMART |
1173 | /* function do_ioctl called from net/core/dev.c | 1195 | /* function do_ioctl called from net/core/dev.c |
@@ -1260,6 +1282,9 @@ static struct tty_ldisc_ops sl_ldisc = { | |||
1260 | .close = slip_close, | 1282 | .close = slip_close, |
1261 | .hangup = slip_hangup, | 1283 | .hangup = slip_hangup, |
1262 | .ioctl = slip_ioctl, | 1284 | .ioctl = slip_ioctl, |
1285 | #ifdef CONFIG_COMPAT | ||
1286 | .compat_ioctl = slip_compat_ioctl, | ||
1287 | #endif | ||
1263 | .receive_buf = slip_receive_buf, | 1288 | .receive_buf = slip_receive_buf, |
1264 | .write_wakeup = slip_write_wakeup, | 1289 | .write_wakeup = slip_write_wakeup, |
1265 | }; | 1290 | }; |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 27945049c9e1..3c325d77939b 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/lapb.h> | 33 | #include <linux/lapb.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/rtnetlink.h> | 35 | #include <linux/rtnetlink.h> |
36 | #include <linux/compat.h> | ||
36 | #include "x25_asy.h" | 37 | #include "x25_asy.h" |
37 | 38 | ||
38 | #include <net/x25device.h> | 39 | #include <net/x25device.h> |
@@ -705,6 +706,21 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file, | |||
705 | } | 706 | } |
706 | } | 707 | } |
707 | 708 | ||
709 | #ifdef CONFIG_COMPAT | ||
710 | static long x25_asy_compat_ioctl(struct tty_struct *tty, struct file *file, | ||
711 | unsigned int cmd, unsigned long arg) | ||
712 | { | ||
713 | switch (cmd) { | ||
714 | case SIOCGIFNAME: | ||
715 | case SIOCSIFHWADDR: | ||
716 | return x25_asy_ioctl(tty, file, cmd, | ||
717 | (unsigned long)compat_ptr(arg)); | ||
718 | } | ||
719 | |||
720 | return -ENOIOCTLCMD; | ||
721 | } | ||
722 | #endif | ||
723 | |||
708 | static int x25_asy_open_dev(struct net_device *dev) | 724 | static int x25_asy_open_dev(struct net_device *dev) |
709 | { | 725 | { |
710 | struct x25_asy *sl = netdev_priv(dev); | 726 | struct x25_asy *sl = netdev_priv(dev); |
@@ -754,6 +770,9 @@ static struct tty_ldisc_ops x25_ldisc = { | |||
754 | .open = x25_asy_open_tty, | 770 | .open = x25_asy_open_tty, |
755 | .close = x25_asy_close_tty, | 771 | .close = x25_asy_close_tty, |
756 | .ioctl = x25_asy_ioctl, | 772 | .ioctl = x25_asy_ioctl, |
773 | #ifdef CONFIG_COMPAT | ||
774 | .compat_ioctl = x25_asy_compat_ioctl, | ||
775 | #endif | ||
757 | .receive_buf = x25_asy_receive_buf, | 776 | .receive_buf = x25_asy_receive_buf, |
758 | .write_wakeup = x25_asy_write_wakeup, | 777 | .write_wakeup = x25_asy_write_wakeup, |
759 | }; | 778 | }; |
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index ea6a87c19319..698aade79d40 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -106,6 +106,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; | |||
106 | #include <linux/serial.h> | 106 | #include <linux/serial.h> |
107 | #include <linux/serialP.h> | 107 | #include <linux/serialP.h> |
108 | #include <linux/rcupdate.h> | 108 | #include <linux/rcupdate.h> |
109 | #include <linux/compat.h> | ||
109 | #include <net/arp.h> | 110 | #include <net/arp.h> |
110 | #include <net/net_namespace.h> | 111 | #include <net/net_namespace.h> |
111 | 112 | ||
@@ -2725,6 +2726,19 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file, | |||
2725 | return 0; | 2726 | return 0; |
2726 | } | 2727 | } |
2727 | 2728 | ||
2729 | #ifdef CONFIG_COMPAT | ||
2730 | static long strip_compat_ioctl(struct tty_struct *tty, struct file *file, | ||
2731 | unsigned int cmd, unsigned long arg) | ||
2732 | { | ||
2733 | switch (cmd) { | ||
2734 | case SIOCGIFNAME: | ||
2735 | case SIOCSIFHWADDR: | ||
2736 | return strip_ioctl(tty, file, cmd, | ||
2737 | (unsigned long)compat_ptr(arg)); | ||
2738 | } | ||
2739 | return -ENOIOCTLCMD; | ||
2740 | } | ||
2741 | #endif | ||
2728 | 2742 | ||
2729 | /************************************************************************/ | 2743 | /************************************************************************/ |
2730 | /* Initialization */ | 2744 | /* Initialization */ |
@@ -2736,6 +2750,9 @@ static struct tty_ldisc_ops strip_ldisc = { | |||
2736 | .open = strip_open, | 2750 | .open = strip_open, |
2737 | .close = strip_close, | 2751 | .close = strip_close, |
2738 | .ioctl = strip_ioctl, | 2752 | .ioctl = strip_ioctl, |
2753 | #ifdef CONFIG_COMPAT | ||
2754 | .compat_ioctl = strip_compat_ioctl, | ||
2755 | #endif | ||
2739 | .receive_buf = strip_receive_buf, | 2756 | .receive_buf = strip_receive_buf, |
2740 | .write_wakeup = strip_write_some_more, | 2757 | .write_wakeup = strip_write_some_more, |
2741 | }; | 2758 | }; |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index c562e9a4da70..f4a5a01fc661 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -2020,8 +2020,6 @@ COMPATIBLE_IOCTL(FIOGETOWN) | |||
2020 | COMPATIBLE_IOCTL(SIOCGPGRP) | 2020 | COMPATIBLE_IOCTL(SIOCGPGRP) |
2021 | COMPATIBLE_IOCTL(SIOCATMARK) | 2021 | COMPATIBLE_IOCTL(SIOCATMARK) |
2022 | COMPATIBLE_IOCTL(SIOCSIFLINK) | 2022 | COMPATIBLE_IOCTL(SIOCSIFLINK) |
2023 | COMPATIBLE_IOCTL(SIOCSIFENCAP) | ||
2024 | COMPATIBLE_IOCTL(SIOCGIFENCAP) | ||
2025 | COMPATIBLE_IOCTL(SIOCSIFNAME) | 2023 | COMPATIBLE_IOCTL(SIOCSIFNAME) |
2026 | COMPATIBLE_IOCTL(SIOCSARP) | 2024 | COMPATIBLE_IOCTL(SIOCSARP) |
2027 | COMPATIBLE_IOCTL(SIOCGARP) | 2025 | COMPATIBLE_IOCTL(SIOCGARP) |