[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