aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-12-05 19:45:14 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-05 19:45:14 -0500
commit426e1fa31e0d8e982891e801c80b84b74f209f10 (patch)
treebc53409418ffa918fb3f175639bc5c9245c4219f /net/socket.c
parente1ca87bb1b64b044163e686ff3bb71405156c561 (diff)
parenta4bcc795e9cc84902b86edbfbb755ecb38d11f91 (diff)
Merge branch 'siocghwtstamp' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
Ben Hutchings says: ==================== SIOCGHWTSTAMP ioctl 1. Add the SIOCGHWTSTAMP ioctl and update the timestamping documentation. 2. Implement SIOCGHWTSTAMP in most drivers that support SIOCSHWTSTAMP. 3. Add a test program to exercise SIOC{G,S}HWTSTAMP. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c57
1 files changed, 9 insertions, 48 deletions
diff --git a/net/socket.c b/net/socket.c
index e83c416708af..cd38a785f7d2 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2968,11 +2968,8 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
2968 struct compat_ifreq __user *ifr32) 2968 struct compat_ifreq __user *ifr32)
2969{ 2969{
2970 struct ifreq kifr; 2970 struct ifreq kifr;
2971 struct ifreq __user *uifr;
2972 mm_segment_t old_fs; 2971 mm_segment_t old_fs;
2973 int err; 2972 int err;
2974 u32 data;
2975 void __user *datap;
2976 2973
2977 switch (cmd) { 2974 switch (cmd) {
2978 case SIOCBONDENSLAVE: 2975 case SIOCBONDENSLAVE:
@@ -2989,26 +2986,13 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
2989 set_fs(old_fs); 2986 set_fs(old_fs);
2990 2987
2991 return err; 2988 return err;
2992 case SIOCBONDSLAVEINFOQUERY:
2993 case SIOCBONDINFOQUERY:
2994 uifr = compat_alloc_user_space(sizeof(*uifr));
2995 if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2996 return -EFAULT;
2997
2998 if (get_user(data, &ifr32->ifr_ifru.ifru_data))
2999 return -EFAULT;
3000
3001 datap = compat_ptr(data);
3002 if (put_user(datap, &uifr->ifr_ifru.ifru_data))
3003 return -EFAULT;
3004
3005 return dev_ioctl(net, cmd, uifr);
3006 default: 2989 default:
3007 return -ENOIOCTLCMD; 2990 return -ENOIOCTLCMD;
3008 } 2991 }
3009} 2992}
3010 2993
3011static int siocdevprivate_ioctl(struct net *net, unsigned int cmd, 2994/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
2995static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
3012 struct compat_ifreq __user *u_ifreq32) 2996 struct compat_ifreq __user *u_ifreq32)
3013{ 2997{
3014 struct ifreq __user *u_ifreq64; 2998 struct ifreq __user *u_ifreq64;
@@ -3019,19 +3003,16 @@ static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
3019 if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]), 3003 if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
3020 IFNAMSIZ)) 3004 IFNAMSIZ))
3021 return -EFAULT; 3005 return -EFAULT;
3022 if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data)) 3006 if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
3023 return -EFAULT; 3007 return -EFAULT;
3024 data64 = compat_ptr(data32); 3008 data64 = compat_ptr(data32);
3025 3009
3026 u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64)); 3010 u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
3027 3011
3028 /* Don't check these user accesses, just let that get trapped
3029 * in the ioctl handler instead.
3030 */
3031 if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], 3012 if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
3032 IFNAMSIZ)) 3013 IFNAMSIZ))
3033 return -EFAULT; 3014 return -EFAULT;
3034 if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data)) 3015 if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
3035 return -EFAULT; 3016 return -EFAULT;
3036 3017
3037 return dev_ioctl(net, cmd, u_ifreq64); 3018 return dev_ioctl(net, cmd, u_ifreq64);
@@ -3111,27 +3092,6 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
3111 return err; 3092 return err;
3112} 3093}
3113 3094
3114static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uifr32)
3115{
3116 void __user *uptr;
3117 compat_uptr_t uptr32;
3118 struct ifreq __user *uifr;
3119
3120 uifr = compat_alloc_user_space(sizeof(*uifr));
3121 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
3122 return -EFAULT;
3123
3124 if (get_user(uptr32, &uifr32->ifr_data))
3125 return -EFAULT;
3126
3127 uptr = compat_ptr(uptr32);
3128
3129 if (put_user(uptr, &uifr->ifr_data))
3130 return -EFAULT;
3131
3132 return dev_ioctl(net, SIOCSHWTSTAMP, uifr);
3133}
3134
3135struct rtentry32 { 3095struct rtentry32 {
3136 u32 rt_pad1; 3096 u32 rt_pad1;
3137 struct sockaddr rt_dst; /* target address */ 3097 struct sockaddr rt_dst; /* target address */
@@ -3243,7 +3203,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3243 struct net *net = sock_net(sk); 3203 struct net *net = sock_net(sk);
3244 3204
3245 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) 3205 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
3246 return siocdevprivate_ioctl(net, cmd, argp); 3206 return compat_ifr_data_ioctl(net, cmd, argp);
3247 3207
3248 switch (cmd) { 3208 switch (cmd) {
3249 case SIOCSIFBR: 3209 case SIOCSIFBR:
@@ -3263,8 +3223,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3263 case SIOCBONDENSLAVE: 3223 case SIOCBONDENSLAVE:
3264 case SIOCBONDRELEASE: 3224 case SIOCBONDRELEASE:
3265 case SIOCBONDSETHWADDR: 3225 case SIOCBONDSETHWADDR:
3266 case SIOCBONDSLAVEINFOQUERY:
3267 case SIOCBONDINFOQUERY:
3268 case SIOCBONDCHANGEACTIVE: 3226 case SIOCBONDCHANGEACTIVE:
3269 return bond_ioctl(net, cmd, argp); 3227 return bond_ioctl(net, cmd, argp);
3270 case SIOCADDRT: 3228 case SIOCADDRT:
@@ -3274,8 +3232,11 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3274 return do_siocgstamp(net, sock, cmd, argp); 3232 return do_siocgstamp(net, sock, cmd, argp);
3275 case SIOCGSTAMPNS: 3233 case SIOCGSTAMPNS:
3276 return do_siocgstampns(net, sock, cmd, argp); 3234 return do_siocgstampns(net, sock, cmd, argp);
3235 case SIOCBONDSLAVEINFOQUERY:
3236 case SIOCBONDINFOQUERY:
3277 case SIOCSHWTSTAMP: 3237 case SIOCSHWTSTAMP:
3278 return compat_siocshwtstamp(net, argp); 3238 case SIOCGHWTSTAMP:
3239 return compat_ifr_data_ioctl(net, cmd, argp);
3279 3240
3280 case FIOSETOWN: 3241 case FIOSETOWN:
3281 case SIOCSPGRP: 3242 case SIOCSPGRP: