aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/net/socket.c b/net/socket.c
index 63b53af7379b..fbf80f9fb057 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2990,6 +2990,53 @@ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
2990 return dev_ioctl(net, cmd, &ifreq, NULL); 2990 return dev_ioctl(net, cmd, &ifreq, NULL);
2991} 2991}
2992 2992
2993static int compat_ifreq_ioctl(struct net *net, struct socket *sock,
2994 unsigned int cmd,
2995 struct compat_ifreq __user *uifr32)
2996{
2997 struct ifreq __user *uifr;
2998 int err;
2999
3000 /* Handle the fact that while struct ifreq has the same *layout* on
3001 * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
3002 * which are handled elsewhere, it still has different *size* due to
3003 * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
3004 * resulting in struct ifreq being 32 and 40 bytes respectively).
3005 * As a result, if the struct happens to be at the end of a page and
3006 * the next page isn't readable/writable, we get a fault. To prevent
3007 * that, copy back and forth to the full size.
3008 */
3009
3010 uifr = compat_alloc_user_space(sizeof(*uifr));
3011 if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
3012 return -EFAULT;
3013
3014 err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
3015
3016 if (!err) {
3017 switch (cmd) {
3018 case SIOCGIFFLAGS:
3019 case SIOCGIFMETRIC:
3020 case SIOCGIFMTU:
3021 case SIOCGIFMEM:
3022 case SIOCGIFHWADDR:
3023 case SIOCGIFINDEX:
3024 case SIOCGIFADDR:
3025 case SIOCGIFBRDADDR:
3026 case SIOCGIFDSTADDR:
3027 case SIOCGIFNETMASK:
3028 case SIOCGIFPFLAGS:
3029 case SIOCGIFTXQLEN:
3030 case SIOCGMIIPHY:
3031 case SIOCGMIIREG:
3032 if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
3033 err = -EFAULT;
3034 break;
3035 }
3036 }
3037 return err;
3038}
3039
2993static int compat_sioc_ifmap(struct net *net, unsigned int cmd, 3040static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
2994 struct compat_ifreq __user *uifr32) 3041 struct compat_ifreq __user *uifr32)
2995{ 3042{
@@ -3209,6 +3256,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3209 case SIOCGMIIPHY: 3256 case SIOCGMIIPHY:
3210 case SIOCGMIIREG: 3257 case SIOCGMIIREG:
3211 case SIOCSMIIREG: 3258 case SIOCSMIIREG:
3259 return compat_ifreq_ioctl(net, sock, cmd, argp);
3260
3212 case SIOCSARP: 3261 case SIOCSARP:
3213 case SIOCGARP: 3262 case SIOCGARP:
3214 case SIOCDARP: 3263 case SIOCDARP: