aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-04-17 16:56:11 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-19 17:07:40 -0400
commit0768e17073dc527ccd18ed5f96ce85f9985e9115 (patch)
tree4f9898446f998dd34bd56f5329dcc4bbd97f92d5 /net/socket.c
parent5ce5d8a5a4ae64b281bea7ae028c960f12acae21 (diff)
net: socket: implement 64-bit timestamps
The 'timeval' and 'timespec' data structures used for socket timestamps are going to be redefined in user space based on 64-bit time_t in future versions of the C library to deal with the y2038 overflow problem, which breaks the ABI definition. Unlike many modern ioctl commands, SIOCGSTAMP and SIOCGSTAMPNS do not use the _IOR() macro to encode the size of the transferred data, so it remains ambiguous whether the application uses the old or new layout. The best workaround I could find is rather ugly: we redefine the command code based on the size of the respective data structure with a ternary operator. This lets it get evaluated as late as possible, hopefully after that structure is visible to the caller. We cannot use an #ifdef here, because inux/sockios.h might have been included before any libc header that could determine the size of time_t. The ioctl implementation now interprets the new command codes as always referring to the 64-bit structure on all architectures, while the old architecture specific command code still refers to the old architecture specific layout. The new command number is only used when they are actually different. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/net/socket.c b/net/socket.c
index ab624d42ead5..8d9d4fc7d962 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1164,14 +1164,24 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1164 1164
1165 err = open_related_ns(&net->ns, get_net_ns); 1165 err = open_related_ns(&net->ns, get_net_ns);
1166 break; 1166 break;
1167 case SIOCGSTAMP: 1167 case SIOCGSTAMP_OLD:
1168 case SIOCGSTAMPNS: 1168 case SIOCGSTAMPNS_OLD:
1169 if (!sock->ops->gettstamp) { 1169 if (!sock->ops->gettstamp) {
1170 err = -ENOIOCTLCMD; 1170 err = -ENOIOCTLCMD;
1171 break; 1171 break;
1172 } 1172 }
1173 err = sock->ops->gettstamp(sock, argp, 1173 err = sock->ops->gettstamp(sock, argp,
1174 cmd == SIOCGSTAMP, false); 1174 cmd == SIOCGSTAMP_OLD,
1175 !IS_ENABLED(CONFIG_64BIT));
1176 case SIOCGSTAMP_NEW:
1177 case SIOCGSTAMPNS_NEW:
1178 if (!sock->ops->gettstamp) {
1179 err = -ENOIOCTLCMD;
1180 break;
1181 }
1182 err = sock->ops->gettstamp(sock, argp,
1183 cmd == SIOCGSTAMP_NEW,
1184 false);
1175 break; 1185 break;
1176 default: 1186 default:
1177 err = sock_do_ioctl(net, sock, cmd, arg); 1187 err = sock_do_ioctl(net, sock, cmd, arg);
@@ -3324,11 +3334,11 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3324 case SIOCADDRT: 3334 case SIOCADDRT:
3325 case SIOCDELRT: 3335 case SIOCDELRT:
3326 return routing_ioctl(net, sock, cmd, argp); 3336 return routing_ioctl(net, sock, cmd, argp);
3327 case SIOCGSTAMP: 3337 case SIOCGSTAMP_OLD:
3328 case SIOCGSTAMPNS: 3338 case SIOCGSTAMPNS_OLD:
3329 if (!sock->ops->gettstamp) 3339 if (!sock->ops->gettstamp)
3330 return -ENOIOCTLCMD; 3340 return -ENOIOCTLCMD;
3331 return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP, 3341 return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
3332 !COMPAT_USE_64BIT_TIME); 3342 !COMPAT_USE_64BIT_TIME);
3333 3343
3334 case SIOCBONDSLAVEINFOQUERY: 3344 case SIOCBONDSLAVEINFOQUERY:
@@ -3348,6 +3358,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3348 case SIOCADDDLCI: 3358 case SIOCADDDLCI:
3349 case SIOCDELDLCI: 3359 case SIOCDELDLCI:
3350 case SIOCGSKNS: 3360 case SIOCGSKNS:
3361 case SIOCGSTAMP_NEW:
3362 case SIOCGSTAMPNS_NEW:
3351 return sock_ioctl(file, cmd, arg); 3363 return sock_ioctl(file, cmd, arg);
3352 3364
3353 case SIOCGIFFLAGS: 3365 case SIOCGIFFLAGS: