aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/compat.h41
-rw-r--r--net/socket.c23
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
168struct 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
168struct compat_ifreq { 175struct 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
189struct compat_ifconf { 196struct 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
2630static 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
2630static int bond_ioctl(struct net *net, unsigned int cmd, 2651static 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: