Deepa Dinamani <deepa.ker...@gmail.com> writes:

> Add new socket timeout options that are y2038 safe.
>
> Signed-off-by: Deepa Dinamani <deepa.ker...@gmail.com>
> Acked-by: Willem de Bruijn <will...@google.com>
> Cc: ccaul...@redhat.com
> Cc: da...@davemloft.net
> Cc: del...@gmx.de
> Cc: pau...@samba.org
> Cc: r...@linux-mips.org
> Cc: r...@twiddle.net
> Cc: cluster-de...@redhat.com
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-al...@vger.kernel.org
> Cc: linux-a...@vger.kernel.org
> Cc: linux-m...@vger.kernel.org
> Cc: linux-par...@vger.kernel.org
> Cc: sparcli...@vger.kernel.org
> ---
>  arch/alpha/include/uapi/asm/socket.h  | 12 ++++--
>  arch/mips/include/uapi/asm/socket.h   | 11 +++++-
>  arch/parisc/include/uapi/asm/socket.h | 10 ++++-
>  arch/sparc/include/uapi/asm/socket.h  | 11 +++++-

You touched powerpc in the previous patch but not this one.

That's because we use the asm-generic version I assume. Would be good to
mention in the change log though to avoid any confusion.

cheers

>  include/uapi/asm-generic/socket.h     | 11 +++++-
>  net/core/sock.c                       | 53 ++++++++++++++++++++-------
>  6 files changed, 83 insertions(+), 25 deletions(-)
>
> diff --git a/arch/alpha/include/uapi/asm/socket.h 
> b/arch/alpha/include/uapi/asm/socket.h
> index 9826d1db71d0..0d0fddb7e738 100644
> --- a/arch/alpha/include/uapi/asm/socket.h
> +++ b/arch/alpha/include/uapi/asm/socket.h
> @@ -119,19 +119,25 @@
>  #define SO_TIMESTAMPNS_NEW      64
>  #define SO_TIMESTAMPING_NEW     65
>  
> -#if !defined(__KERNEL__)
> +#define SO_RCVTIMEO_NEW         66
> +#define SO_SNDTIMEO_NEW         67
>  
> -#define      SO_RCVTIMEO SO_RCVTIMEO_OLD
> -#define      SO_SNDTIMEO SO_SNDTIMEO_OLD
> +#if !defined(__KERNEL__)
>  
>  #if __BITS_PER_LONG == 64
>  #define SO_TIMESTAMP         SO_TIMESTAMP_OLD
>  #define SO_TIMESTAMPNS               SO_TIMESTAMPNS_OLD
>  #define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
> +
> +#define SO_RCVTIMEO          SO_RCVTIMEO_OLD
> +#define SO_SNDTIMEO          SO_SNDTIMEO_OLD
>  #else
>  #define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
>  #define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
>  #define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
> +
> +#define SO_RCVTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_RCVTIMEO_OLD : SO_RCVTIMEO_NEW)
> +#define SO_SNDTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_SNDTIMEO_OLD : SO_SNDTIMEO_NEW)
>  #endif
>  
>  #define SCM_TIMESTAMP           SO_TIMESTAMP
> diff --git a/arch/mips/include/uapi/asm/socket.h 
> b/arch/mips/include/uapi/asm/socket.h
> index 96cc0e907f12..eb9f33f8a8b3 100644
> --- a/arch/mips/include/uapi/asm/socket.h
> +++ b/arch/mips/include/uapi/asm/socket.h
> @@ -130,18 +130,25 @@
>  #define SO_TIMESTAMPNS_NEW      64
>  #define SO_TIMESTAMPING_NEW     65
>  
> +#define SO_RCVTIMEO_NEW         66
> +#define SO_SNDTIMEO_NEW         67
> +
>  #if !defined(__KERNEL__)
>  
> -#define      SO_RCVTIMEO SO_RCVTIMEO_OLD
> -#define      SO_SNDTIMEO SO_SNDTIMEO_OLD
>  #if __BITS_PER_LONG == 64
>  #define SO_TIMESTAMP         SO_TIMESTAMP_OLD
>  #define SO_TIMESTAMPNS               SO_TIMESTAMPNS_OLD
>  #define SO_TIMESTAMPING              SO_TIMESTAMPING_OLD
> +
> +#define SO_RCVTIMEO             SO_RCVTIMEO_OLD
> +#define SO_SNDTIMEO             SO_SNDTIMEO_OLD
>  #else
>  #define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
>  #define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
>  #define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
> +
> +#define SO_RCVTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_RCVTIMEO_OLD : SO_RCVTIMEO_NEW)
> +#define SO_SNDTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_SNDTIMEO_OLD : SO_SNDTIMEO_NEW)
>  #endif
>  
>  #define SCM_TIMESTAMP           SO_TIMESTAMP
> diff --git a/arch/parisc/include/uapi/asm/socket.h 
> b/arch/parisc/include/uapi/asm/socket.h
> index 046f0cd9cce4..16e428f03526 100644
> --- a/arch/parisc/include/uapi/asm/socket.h
> +++ b/arch/parisc/include/uapi/asm/socket.h
> @@ -111,18 +111,24 @@
>  #define SO_TIMESTAMPNS_NEW      0x4039
>  #define SO_TIMESTAMPING_NEW     0x403A
>  
> +#define SO_RCVTIMEO_NEW         0x4040
> +#define SO_SNDTIMEO_NEW         0x4041
> +
>  #if !defined(__KERNEL__)
>  
> -#define      SO_RCVTIMEO SO_RCVTIMEO_OLD
> -#define      SO_SNDTIMEO SO_SNDTIMEO_OLD
>  #if __BITS_PER_LONG == 64
>  #define SO_TIMESTAMP         SO_TIMESTAMP_OLD
>  #define SO_TIMESTAMPNS               SO_TIMESTAMPNS_OLD
>  #define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
> +#define SO_RCVTIMEO          SO_RCVTIMEO_OLD
> +#define SO_SNDTIMEO          SO_SNDTIMEO_OLD
>  #else
>  #define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
>  #define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
>  #define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
> +
> +#define SO_RCVTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_RCVTIMEO_OLD : SO_RCVTIMEO_NEW)
> +#define SO_SNDTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_SNDTIMEO_OLD : SO_SNDTIMEO_NEW)
>  #endif
>  
>  #define SCM_TIMESTAMP           SO_TIMESTAMP
> diff --git a/arch/sparc/include/uapi/asm/socket.h 
> b/arch/sparc/include/uapi/asm/socket.h
> index 342ffdc3b424..8c9f74a66b55 100644
> --- a/arch/sparc/include/uapi/asm/socket.h
> +++ b/arch/sparc/include/uapi/asm/socket.h
> @@ -112,19 +112,26 @@
>  #define SO_TIMESTAMPNS_NEW       0x0042
>  #define SO_TIMESTAMPING_NEW      0x0043
>  
> +#define SO_RCVTIMEO_NEW          0x0044
> +#define SO_SNDTIMEO_NEW          0x0045
> +
>  #if !defined(__KERNEL__)
>  
> -#define SO_RCVTIMEO              SO_RCVTIMEO_OLD
> -#define SO_SNDTIMEO              SO_SNDTIMEO_OLD
>  
>  #if __BITS_PER_LONG == 64
>  #define SO_TIMESTAMP         SO_TIMESTAMP_OLD
>  #define SO_TIMESTAMPNS               SO_TIMESTAMPNS_OLD
>  #define SO_TIMESTAMPING              SO_TIMESTAMPING_OLD
> +
> +#define SO_RCVTIMEO          SO_RCVTIMEO_OLD
> +#define SO_SNDTIMEO          SO_SNDTIMEO_OLD
>  #else
>  #define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
>  #define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
>  #define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
> +
> +#define SO_RCVTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_RCVTIMEO_OLD : SO_RCVTIMEO_NEW)
> +#define SO_SNDTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_SNDTIMEO_OLD : SO_SNDTIMEO_NEW)
>  #endif
>  
>  #define SCM_TIMESTAMP          SO_TIMESTAMP
> diff --git a/include/uapi/asm-generic/socket.h 
> b/include/uapi/asm-generic/socket.h
> index c56b8b487c12..c8b430cb6dc4 100644
> --- a/include/uapi/asm-generic/socket.h
> +++ b/include/uapi/asm-generic/socket.h
> @@ -114,19 +114,26 @@
>  #define SO_TIMESTAMPNS_NEW      64
>  #define SO_TIMESTAMPING_NEW     65
>  
> +#define SO_RCVTIMEO_NEW         66
> +#define SO_SNDTIMEO_NEW         67
> +
>  #if !defined(__KERNEL__)
>  
> -#define      SO_RCVTIMEO SO_RCVTIMEO_OLD
> -#define      SO_SNDTIMEO SO_SNDTIMEO_OLD
>  #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
>  /* on 64-bit and x32, avoid the ?: operator */
>  #define SO_TIMESTAMP         SO_TIMESTAMP_OLD
>  #define SO_TIMESTAMPNS               SO_TIMESTAMPNS_OLD
>  #define SO_TIMESTAMPING              SO_TIMESTAMPING_OLD
> +
> +#define SO_RCVTIMEO          SO_RCVTIMEO_OLD
> +#define SO_SNDTIMEO          SO_SNDTIMEO_OLD
>  #else
>  #define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
>  #define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
>  #define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
> +
> +#define SO_RCVTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_RCVTIMEO_OLD : SO_RCVTIMEO_NEW)
> +#define SO_SNDTIMEO (sizeof(time_t) == sizeof(__kernel_long_t) ? 
> SO_SNDTIMEO_OLD : SO_SNDTIMEO_NEW)
>  #endif
>  
>  #define SCM_TIMESTAMP           SO_TIMESTAMP
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 27b40002b780..a8904ae40713 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -335,9 +335,10 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff 
> *skb)
>  }
>  EXPORT_SYMBOL(__sk_backlog_rcv);
>  
> -static int sock_get_timeout(long timeo, void *optval)
> +static int sock_get_timeout(long timeo, void *optval, bool old_timeval)
>  {
> -     struct __kernel_old_timeval tv;
> +     struct __kernel_sock_timeval tv;
> +     int size;
>  
>       if (timeo == MAX_SCHEDULE_TIMEOUT) {
>               tv.tv_sec = 0;
> @@ -353,13 +354,23 @@ static int sock_get_timeout(long timeo, void *optval)
>               return sizeof(tv32);
>       }
>  
> -     *(struct __kernel_old_timeval *)optval = tv;
> -     return sizeof(tv);
> +     if (old_timeval) {
> +             struct __kernel_old_timeval old_tv;
> +             old_tv.tv_sec = tv.tv_sec;
> +             old_tv.tv_usec = tv.tv_usec;
> +             *(struct __kernel_old_timeval *)optval = old_tv;
> +             size = sizeof(old_tv);
> +     } else {
> +             *(struct __kernel_sock_timeval *)optval = tv;
> +             size = sizeof(tv);
> +     }
> +
> +     return size;
>  }
>  
> -static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
> +static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen, 
> bool old_timeval)
>  {
> -     struct __kernel_old_timeval tv;
> +     struct __kernel_sock_timeval tv;
>  
>       if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {
>               struct old_timeval32 tv32;
> @@ -371,6 +382,15 @@ static int sock_set_timeout(long *timeo_p, char __user 
> *optval, int optlen)
>                       return -EFAULT;
>               tv.tv_sec = tv32.tv_sec;
>               tv.tv_usec = tv32.tv_usec;
> +     } else if (old_timeval) {
> +             struct __kernel_old_timeval old_tv;
> +
> +             if (optlen < sizeof(old_tv))
> +                     return -EINVAL;
> +             if (copy_from_user(&old_tv, optval, sizeof(old_tv)))
> +                     return -EFAULT;
> +             tv.tv_sec = old_tv.tv_sec;
> +             tv.tv_usec = old_tv.tv_usec;
>       } else {
>               if (optlen < sizeof(tv))
>                       return -EINVAL;
> @@ -394,8 +414,8 @@ static int sock_set_timeout(long *timeo_p, char __user 
> *optval, int optlen)
>       *timeo_p = MAX_SCHEDULE_TIMEOUT;
>       if (tv.tv_sec == 0 && tv.tv_usec == 0)
>               return 0;
> -     if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT/HZ - 1))
> -             *timeo_p = tv.tv_sec * HZ + DIV_ROUND_UP(tv.tv_usec, 
> USEC_PER_SEC / HZ);
> +     if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1))
> +             *timeo_p = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned 
> long)tv.tv_usec, USEC_PER_SEC / HZ);
>       return 0;
>  }
>  
> @@ -942,11 +962,13 @@ int sock_setsockopt(struct socket *sock, int level, int 
> optname,
>               break;
>  
>       case SO_RCVTIMEO_OLD:
> -             ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen);
> +     case SO_RCVTIMEO_NEW:
> +             ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen, 
> optname == SO_RCVTIMEO_OLD);
>               break;
>  
>       case SO_SNDTIMEO_OLD:
> -             ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen);
> +     case SO_SNDTIMEO_NEW:
> +             ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen, 
> optname == SO_SNDTIMEO_OLD);
>               break;
>  
>       case SO_ATTACH_FILTER:
> @@ -1171,6 +1193,7 @@ int sock_getsockopt(struct socket *sock, int level, int 
> optname,
>               struct linger ling;
>               struct old_timeval32 tm32;
>               struct __kernel_old_timeval tm;
> +             struct  __kernel_sock_timeval stm;
>               struct sock_txtime txtime;
>       } v;
>  
> @@ -1279,12 +1302,14 @@ int sock_getsockopt(struct socket *sock, int level, 
> int optname,
>               v.val = sk->sk_tsflags;
>               break;
>  
> -     case SO_RCVTIMEO:
> -             lv = sock_get_timeout(sk->sk_rcvtimeo, &v);
> +     case SO_RCVTIMEO_OLD:
> +     case SO_RCVTIMEO_NEW:
> +             lv = sock_get_timeout(sk->sk_rcvtimeo, &v, SO_RCVTIMEO_OLD == 
> optname);
>               break;
>  
> -     case SO_SNDTIMEO:
> -             lv = sock_get_timeout(sk->sk_sndtimeo, &v);
> +     case SO_SNDTIMEO_OLD:
> +     case SO_SNDTIMEO_NEW:
> +             lv = sock_get_timeout(sk->sk_sndtimeo, &v, SO_SNDTIMEO_OLD == 
> optname);
>               break;
>  
>       case SO_RCVLOWAT:
> -- 
> 2.17.1

Reply via email to