From 3d318d40907964168cc0fdda9492b80f11c1dddf Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 23 Jun 2023 11:10:45 +0200 Subject: [PATCH] swrap: Provide a fcntl64() We want to run with and without large file support. It depends on if the application is build with large file support so it will either choose fcntl or fcntl64. Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- src/socket_wrapper.c | 112 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 20 deletions(-) diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index aa559b8..c759d35 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -627,10 +627,9 @@ struct swrap_libc_symbols { SWRAP_SYMBOL_ENTRY(connect); SWRAP_SYMBOL_ENTRY(dup); SWRAP_SYMBOL_ENTRY(dup2); + SWRAP_SYMBOL_ENTRY(fcntl); #ifdef HAVE_FCNTL64 SWRAP_SYMBOL_ENTRY(fcntl64); -#else - SWRAP_SYMBOL_ENTRY(fcntl); #endif SWRAP_SYMBOL_ENTRY(fopen); #ifdef HAVE_FOPEN64 @@ -1001,27 +1000,27 @@ 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. - */ + rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg); + + return rc; +} + #ifdef HAVE_FCNTL64 +DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE +static int libc_vfcntl64(int fd, int cmd, va_list ap) +{ + void *arg; + int rc; + + swrap_bind_symbol_all(); + + arg = va_arg(ap, void *); + rc = swrap.libc.symbols._libc_fcntl64.f(fd, cmd, arg); -#else - rc = swrap.libc.symbols._libc_fcntl.f(fd, cmd, arg); -#endif return rc; } +#endif static int libc_getpeername(int sockfd, struct sockaddr *addr, @@ -1463,10 +1462,9 @@ static void __swrap_bind_symbol_all_once(void) swrap_bind_symbol_libsocket(connect); swrap_bind_symbol_libc(dup); swrap_bind_symbol_libc(dup2); + swrap_bind_symbol_libc(fcntl); #ifdef HAVE_FCNTL64 swrap_bind_symbol_libc(fcntl64); -#else - swrap_bind_symbol_libc(fcntl); #endif swrap_bind_symbol_libc(fopen); #ifdef HAVE_FOPEN64 @@ -8536,6 +8534,80 @@ int fcntl(int fd, int cmd, ...) return rc; } +/**************************** + * FCNTL64 + ***************************/ + +#ifdef HAVE_FCNTL64 +static int swrap_vfcntl64(int fd, int cmd, va_list va) +{ + struct socket_info *si; + int rc, dup_fd, idx; + + idx = find_socket_info_index(fd); + if (idx == -1) { + return libc_vfcntl64(fd, cmd, va); + } + + si = swrap_get_socket_info(idx); + + switch (cmd) { + case F_DUPFD: + dup_fd = libc_vfcntl64(fd, cmd, va); + if (dup_fd == -1) { + int saved_errno = errno; + errno = saved_errno; + return -1; + } + + /* Make sure we don't have an entry for the fd */ + swrap_remove_stale(dup_fd); + + if ((size_t)dup_fd >= socket_fds_max) { + SWRAP_LOG(SWRAP_LOG_ERROR, + "The max socket index limit of %zu has been reached, " + "trying to add %d", + socket_fds_max, + dup_fd); + libc_close(dup_fd); + errno = EMFILE; + return -1; + } + + SWRAP_LOCK_SI(si); + + swrap_inc_refcount(si); + + SWRAP_UNLOCK_SI(si); + + + set_socket_info_index(dup_fd, idx); + + rc = dup_fd; + break; + default: + rc = libc_vfcntl64(fd, cmd, va); + break; + } + + return rc; +} + +int fcntl64(int fd, int cmd, ...) +{ + va_list va; + int rc; + + va_start(va, cmd); + + rc = swrap_vfcntl64(fd, cmd, va); + + va_end(va); + + return rc; +} +#endif + /**************************** * EVENTFD ***************************/ -- 2.34.1