diff options
-rw-r--r-- | include/linux/compat.h | 41 | ||||
-rw-r--r-- | net/socket.c | 23 |
2 files changed, 47 insertions, 17 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h index 224c7a896172..ef68119a4fd2 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -165,25 +165,32 @@ struct compat_ifmap { | |||
165 | unsigned char port; | 165 | unsigned char port; |
166 | }; | 166 | }; |
167 | 167 | ||
168 | struct compat_if_settings | ||
169 | { | ||
170 | unsigned int type; /* Type of physical device or protocol */ | ||
171 | unsigned int size; /* Size of the data allocated by the caller */ | ||
172 | compat_uptr_t ifs_ifsu; /* union of pointers */ | ||
173 | }; | ||
174 | |||
168 | struct compat_ifreq { | 175 | struct compat_ifreq { |
169 | union { | 176 | union { |
170 | char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ | 177 | char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ |
171 | } ifr_ifrn; | 178 | } ifr_ifrn; |
172 | union { | 179 | union { |
173 | struct sockaddr ifru_addr; | 180 | struct sockaddr ifru_addr; |
174 | struct sockaddr ifru_dstaddr; | 181 | struct sockaddr ifru_dstaddr; |
175 | struct sockaddr ifru_broadaddr; | 182 | struct sockaddr ifru_broadaddr; |
176 | struct sockaddr ifru_netmask; | 183 | struct sockaddr ifru_netmask; |
177 | struct sockaddr ifru_hwaddr; | 184 | struct sockaddr ifru_hwaddr; |
178 | short ifru_flags; | 185 | short ifru_flags; |
179 | compat_int_t ifru_ivalue; | 186 | compat_int_t ifru_ivalue; |
180 | compat_int_t ifru_mtu; | 187 | compat_int_t ifru_mtu; |
181 | struct compat_ifmap ifru_map; | 188 | struct compat_ifmap ifru_map; |
182 | char ifru_slave[IFNAMSIZ]; /* Just fits the size */ | 189 | char ifru_slave[IFNAMSIZ]; /* Just fits the size */ |
183 | char ifru_newname[IFNAMSIZ]; | 190 | char ifru_newname[IFNAMSIZ]; |
184 | compat_caddr_t ifru_data; | 191 | compat_caddr_t ifru_data; |
185 | /* XXXX? ifru_settings should be here */ | 192 | struct compat_if_settings ifru_settings; |
186 | } ifr_ifru; | 193 | } ifr_ifru; |
187 | }; | 194 | }; |
188 | 195 | ||
189 | struct compat_ifconf { | 196 | struct compat_ifconf { |
diff --git a/net/socket.c b/net/socket.c index 224e7f73fdf0..befd9f5b1620 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2627,6 +2627,27 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) | |||
2627 | return dev_ioctl(net, SIOCETHTOOL, ifr); | 2627 | return dev_ioctl(net, SIOCETHTOOL, ifr); |
2628 | } | 2628 | } |
2629 | 2629 | ||
2630 | static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32) | ||
2631 | { | ||
2632 | void __user *uptr; | ||
2633 | compat_uptr_t uptr32; | ||
2634 | struct ifreq __user *uifr; | ||
2635 | |||
2636 | uifr = compat_alloc_user_space(sizeof (*uifr)); | ||
2637 | if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq))) | ||
2638 | return -EFAULT; | ||
2639 | |||
2640 | if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu)) | ||
2641 | return -EFAULT; | ||
2642 | |||
2643 | uptr = compat_ptr(uptr32); | ||
2644 | |||
2645 | if (put_user(uptr, &uifr->ifr_settings.ifs_ifsu.raw_hdlc)) | ||
2646 | return -EFAULT; | ||
2647 | |||
2648 | return dev_ioctl(net, SIOCWANDEV, uifr); | ||
2649 | } | ||
2650 | |||
2630 | static int bond_ioctl(struct net *net, unsigned int cmd, | 2651 | static int bond_ioctl(struct net *net, unsigned int cmd, |
2631 | struct compat_ifreq __user *ifr32) | 2652 | struct compat_ifreq __user *ifr32) |
2632 | { | 2653 | { |
@@ -3058,6 +3079,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, | |||
3058 | return dev_ifconf(net, argp); | 3079 | return dev_ifconf(net, argp); |
3059 | case SIOCETHTOOL: | 3080 | case SIOCETHTOOL: |
3060 | return ethtool_ioctl(net, argp); | 3081 | return ethtool_ioctl(net, argp); |
3082 | case SIOCWANDEV: | ||
3083 | return compat_siocwandev(net, argp); | ||
3061 | case SIOCBONDENSLAVE: | 3084 | case SIOCBONDENSLAVE: |
3062 | case SIOCBONDRELEASE: | 3085 | case SIOCBONDRELEASE: |
3063 | case SIOCBONDSETHWADDR: | 3086 | case SIOCBONDSETHWADDR: |