Messages in this thread | | | Date | Wed, 19 Jul 2023 11:03:19 +0000 | From | "Drew B." <> | Subject | Misbehavior with setsockopt timeval structure with -fpack-struct enabled |
| |
Hi everyone! I've got a very strange behavior on Linux and OS X build of the same source code. To be specific, when I try to set socket timeout option:
... struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 1; ret = setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); ...
with -fpack-struct enabled, on Linux machine the size of timeval struct is 16 bytes (as well as unpacked), while on OS X it's 12 for packed and 16 for unpacked. In which case I get an error while trying to apply the setting to the socket. I dug a little bit deeper and the following piece of code in net/core/sock.c:
... int sock_copy_user_timeval(struct __kernel_sock_timeval *tv, sockptr_t optval, int optlen, bool old_timeval) { if (old_timeval && in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { struct old_timeval32 tv32;
if (optlen < sizeof(tv32)) return -EINVAL;
if (copy_from_sockptr(&tv32, optval, sizeof(tv32))) 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_sockptr(&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; if (copy_from_sockptr(tv, optval, sizeof(*tv))) return -EFAULT; }
return 0; } EXPORT_SYMBOL(sock_copy_user_timeval); ...
So, to be specific (same or similar logics goes through the function in respective places): if (optlen < sizeof(tv32)) return -EINVAL; Which means, that it doesn't consider whether the structure is packed or not, it always compares against unpacked (?) structure == 16 bytes (for now).
Is it expected?
Kind regards, Drew.
| |