[PATCH v2 05/25] linux: Add fallback for 64-bit time_t SO_{RCV,SND}TIMEO

Adhemerval Zanella adhemerval.zanella@linaro.org
Mon Jun 7 17:52:17 GMT 2021



On 04/06/2021 16:30, Carlos O'Donell wrote:
>> +#ifndef __ASSUME_TIME64_SYSCALLS
>> +static int
>> +setsockopt32 (int fd, int level, int optname, const void *optval,
>> +	      socklen_t len)
>> +{
>> +  int r = -1;
>> +
>> +  if (level != SOL_SOCKET)
>> +    return r;
>> +
>> +  switch (optname)
>> +    {
>> +    case COMPAT_SO_RCVTIMEO_NEW:
>> +    case COMPAT_SO_SNDTIMEO_NEW:
>> +      {
>> +        if (len < sizeof (struct __timeval64))
>> +	  {
>> +	    __set_errno (EINVAL);
>> +	    break;
> 
> Same issue as above with size. Silent truncation required.

For setsockopt I think returning EINVAL is the correct approach here.  POSIX
does not specify that the returned value should silently truncated in the 
case of the options is larger than the input value (as for getsockopt) and
it is what kernel really does:

net/core/sock.c:

 364 static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
 365                             bool old_timeval)
 366 {
 367         struct __kernel_sock_timeval tv;
 368 
 369         if (old_timeval && in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {
 370                 struct old_timeval32 tv32;
 371 
 372                 if (optlen < sizeof(tv32))
 373                         return -EINVAL;
 374 
 375                 if (copy_from_sockptr(&tv32, optval, sizeof(tv32)))
 376                         return -EFAULT;
 377                 tv.tv_sec = tv32.tv_sec;
 378                 tv.tv_usec = tv32.tv_usec;
 379         } else if (old_timeval) {
 380                 struct __kernel_old_timeval old_tv;
 381 
 382                 if (optlen < sizeof(old_tv))
 383                         return -EINVAL;
 384                 if (copy_from_sockptr(&old_tv, optval, sizeof(old_tv)))
 385                         return -EFAULT;
 386                 tv.tv_sec = old_tv.tv_sec;
 387                 tv.tv_usec = old_tv.tv_usec;
 388         } else {
 389                 if (optlen < sizeof(tv))
 390                         return -EINVAL;
 391                 if (copy_from_sockptr(&tv, optval, sizeof(tv)))
 392                         return -EFAULT;
 393         }



More information about the Libc-alpha mailing list