mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Revert {send,sendm,recv,recvm}msg conformance changes
After some discussion in libc-alpha about this POSIX compliance fix, I see that GLIBC should indeed revert back to previous definition of msghdr and cmsghdr and implementation of sendmsg, recvmsg, sendmmsg, recvmmsg due some reasons: * The possible issue where the syscalls wrapper add the compatibility layer is quite limited in scope and range. And kernel current also add some limits to the values on the internal msghdr and cmsghdr fields: - msghdr::msg_iovlen larger than UIO_MAXIOV (1024) returns EMSGSIZE. - msghdr::msg_controllen larger than INT_MAX returns ENOBUFS. * There is a small performance hit for recvmsg/sendmsg/recmmsg which is neglectable, but it is a big hit for sendmmsg since now instead of calling the syscall for the packed structure, GLIBC is calling multiple sendmsg. This defeat the very existence of the syscall. * It currently breaks libsanitizer build on GCC [1] (I fixed on compiler-rt). However the fix is incomplete because it does add any runtime check since libsanitizer currently does not have any facility to intercept symbols with multiple version [2]. This, along with incorret dlsym/dlvsym return for versioned symbol due another bug [3], makes hard to interpose versioned symbols. Also, current approach of fixing GCC PR#71445 leads to half-baked solutions without versioned symbol interposing. This patch basically reverts commits2f0dc39029
,222c2d7f43
,af7f7c7ec8
. I decided to not revertabf29edd4a
(Adjust kernel-features.h defaults for recvmsg and sendmsg) mainly because it does not really address the POSIX compliance original issue and also adds some cleanups. Tested on x86, i386, s390, s390x, aarch64, and powerpc64le. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71445 [2] https://github.com/google/sanitizers/issues/628 [3] https://sourceware.org/bugzilla/show_bug.cgi?id=14932 * conform/data/sys/socket.h-data (msghdr.msg_iovlen): Add xfail-. (msghdr.msg_controllen): Likewise. (cmsghdr.cmsg_len): Likewise. * nptl/Makefile (libpthread-routines): Remove ptw-oldrecvmsg and ptw-oldsendmsg. (CFLAGS-oldrecvmsg.c): Remove rule. (CFLAGS-oldsendmsg.c): Likewise. (CFLAGS-recvmsg.c): Add rule. (CFLAGS-sendmsg.c): Likewise. * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Remove oldrecvmsg, oldsendmsg, oldrecvmmsg, oldsendmmsg. (CFLAGS-recvmsg.c): Remove rule. (CFLAGS-sendmsg.c): Likewise. (CFLAGS-oldrecvmsg.c): Likewise. (CFLAGS-oldsendmsg.c): Likewise. (CFLAGS-recvmmsg.c): Likewise. * sysdeps/unix/sysv/linux/bits/socket.h (msghdr.msg_iovlen): Revert to kernel defined interfaces. (msghdr.msg_controllen): Likewise. (cmsghdr.cmsg_len): Likewise. (msghdr.__glibc_reserved1): Remove member. (msghdr.__glibc_reserved2): Likewise. (cmsghdr.__glibc_reserved1): Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: Remove file. * sysdeps/unix/sysv/linux/oldrecvmsg.c: Likewise. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/oldsendmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c: Revert back to previous version. * sysdeps/unix/sysv/linux/recvmsg.c: Likewise. * sysdeps/unix/sysv/linux/sendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/sendmsg.c: Likewise. * sysdeps/unix/sysv/linux/aarch64/Versions [libc] (GLIBC_2.24): Remove recvmsg and sendmsg. * sysdeps/unix/sysv/linux/alpha/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/hppa/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/i386/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/m68k/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/microblaze/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/mips/mips32/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/nios2/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/powerpc/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/sh/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/sparc/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/tile/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/x86_64/Versions [libc] (GLIBC_2.24): Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/Versions: Remove file * sysdeps/unix/sysv/linux/x86_64/64/Versions: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/Versions: Likewise. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Remove new 2.24 version for {recv,send,recm,sendm}msg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
This commit is contained in:
@ -16,10 +16,12 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <socketcall.h>
|
||||
|
||||
#include <sysdep-cancel.h>
|
||||
#include <shlib-compat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <kernel-features.h>
|
||||
|
||||
/* Do not use the recvmmsg syscall on socketcall architectures unless
|
||||
it was added at the same time as the socketcall support or can be
|
||||
@ -30,39 +32,31 @@
|
||||
# undef __NR_recvmmsg
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
adjust_mmsghdr (struct mmsghdr *vmessages, unsigned int vlen)
|
||||
#ifdef __NR_recvmmsg
|
||||
int
|
||||
recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
struct timespec *tmo)
|
||||
{
|
||||
#if __WORDSIZE == 64
|
||||
/* POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
|
||||
to be int and socklen_t respectively. However Linux defines it as
|
||||
both size_t. So for 64-bit it requires some adjustments by zeroing
|
||||
the pad fields. */
|
||||
struct mmsghdr *vmhdr = vmessages;
|
||||
for (unsigned int i = 0; i != 0; i--, vmhdr++)
|
||||
{
|
||||
vmhdr->msg_hdr.__glibc_reserved1 = 0;
|
||||
vmhdr->msg_hdr.__glibc_reserved2 = 0;
|
||||
}
|
||||
#endif
|
||||
return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
|
||||
}
|
||||
#elif defined __NR_socketcall
|
||||
# include <socketcall.h>
|
||||
# ifdef __ASSUME_RECVMMSG_SOCKETCALL
|
||||
int
|
||||
recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
struct timespec *tmo)
|
||||
{
|
||||
return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
|
||||
}
|
||||
# else
|
||||
static int have_recvmmsg;
|
||||
|
||||
int
|
||||
__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
|
||||
int flags, struct timespec *tmo)
|
||||
recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
|
||||
struct timespec *tmo)
|
||||
{
|
||||
#ifdef __NR_recvmmsg
|
||||
adjust_mmsghdr (vmessages, vlen);
|
||||
return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
|
||||
#elif defined __NR_socketcall
|
||||
# ifdef __ASSUME_RECVMMSG_SOCKETCALL
|
||||
adjust_mmsghdr (vmessages, vlen);
|
||||
return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
|
||||
# else
|
||||
static int have_recvmmsg;
|
||||
if (__glibc_likely (have_recvmmsg >= 0))
|
||||
{
|
||||
adjust_mmsghdr (vmessages, vlen);
|
||||
int ret = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags,
|
||||
tmo);
|
||||
/* The kernel returns -EINVAL for unknown socket operations.
|
||||
@ -92,19 +86,8 @@ __recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
|
||||
}
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
# endif /* __ASSUME_RECVMMSG_SOCKETCALL */
|
||||
#else
|
||||
# define STUB 1
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#ifdef STUB
|
||||
stub_warning (recvmmsg)
|
||||
#endif
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
versioned_symbol (libc, __recvmmsg, recvmmsg, GLIBC_2_24);
|
||||
#else
|
||||
weak_alias (__recvmmsg, recvmmsg)
|
||||
# include <socket/recvmmsg.c>
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user