From df918708717c084ec9048be2864edcde81816108 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 5 May 2023 13:34:00 +1200 Subject: [PATCH] Add fix for incorrect mapping of fcntl64() -> fcntl(), causing locking failures We need to call fcntl64() if possible for 32-bit hosts This is a strange case of socket_wrapper breaking normal file operation. Newer glibc has introduced fcntl64 and symbol renaming but the end function call was not caught by the automatic rename. This means socket_wrapper would call fcntl(), not fcntl64 in libc and this would do a "struct flock" -> "struct flock64" translation on the supplied argument, despite this being already a flock64 from the caller. This in turn changed the lock offset values (eg to 0, 0). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15367 Signed-off-by: Andrew Bartlett Reviewed-by: Andreas Schneider --- ConfigureChecks.cmake | 1 + src/socket_wrapper.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index b820a65..c99e2ae 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -80,6 +80,7 @@ check_function_exists(__close_nocancel HAVE___CLOSE_NOCANCEL) check_function_exists(recvmmsg HAVE_RECVMMSG) check_function_exists(sendmmsg HAVE_SENDMMSG) check_function_exists(syscall HAVE_SYSCALL) +check_function_exists(fcntl64 HAVE_FCNTL64) if (UNIX) find_library(DLFCN_LIBRARY dl) diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index bf4a976..de2f732 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -611,7 +611,11 @@ struct swrap_libc_symbols { SWRAP_SYMBOL_ENTRY(connect); SWRAP_SYMBOL_ENTRY(dup); SWRAP_SYMBOL_ENTRY(dup2); +#ifdef HAVE_FCNTL64 + SWRAP_SYMBOL_ENTRY(fcntl64); +#else SWRAP_SYMBOL_ENTRY(fcntl); +#endif SWRAP_SYMBOL_ENTRY(fopen); #ifdef HAVE_FOPEN64 SWRAP_SYMBOL_ENTRY(fopen64); @@ -978,7 +982,24 @@ static int libc_vfcntl(int fd, int cmd, va_list ap) arg = va_arg(ap, void *); + /* + * If fcntl64 exists then this is a system were fcntl is + * renamed (including when building this file), and so we must + * assume that the binary under test was built with + * -D_FILE_OFFSET_BITS=64 and pass on to fcntl64. + * + * If we are wrong, then fcntl is unwrapped, but while that is + * not ideal, is is also unlikely. + * + * In any case, it is always wrong to map fcntl64() to fcntl() + * as this will cause a thunk from struct flock -> flock64 + * that the caller had already prepared for. + */ +#ifdef HAVE_FCNTL64 + rc = swrap.libc.symbols._libc_fcntl64.f(fd, cmd, arg); +#else rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg); +#endif return rc; } @@ -1400,7 +1421,11 @@ static void __swrap_bind_symbol_all_once(void) swrap_bind_symbol_libsocket(connect); swrap_bind_symbol_libc(dup); swrap_bind_symbol_libc(dup2); +#ifdef HAVE_FCNTL64 + swrap_bind_symbol_libc(fcntl64); +#else swrap_bind_symbol_libc(fcntl); +#endif swrap_bind_symbol_libc(fopen); #ifdef HAVE_FOPEN64 swrap_bind_symbol_libc(fopen64); -- 2.34.1