The branch, master has been updated via 81a8970 gitlab-ci: Add Ubuntu 32bit build via 3d318d4 swrap: Provide a fcntl64() via 593ab18 swrap: Fix fnctl64() via 51fbe21 tests(cmake): Fix handling of LFS support via 72d3b3c tests: Implement test_fcntl_lock correctly via bbe14cc swrap: Make sure we do not redirect (f)open(at)() or fcntl() via 70ecbaa tests: Do not build test_swrap_unit with LFS support from d8b61a6 Bump version to 1.4.1
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 81a897096588acc658f3834f084ea92c3a8c1746 Author: Andreas Schneider <a...@samba.org> Date: Thu Jun 22 18:30:52 2023 +0200 gitlab-ci: Add Ubuntu 32bit build Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 3d318d40907964168cc0fdda9492b80f11c1dddf Author: Andreas Schneider <a...@samba.org> Date: Fri Jun 23 11:10:45 2023 +0200 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 <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 593ab1862a1d076f30185f7fc03a1fdcf725be56 Author: Andreas Schneider <a...@samba.org> Date: Thu Jun 22 18:32:30 2023 +0200 swrap: Fix fnctl64() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 51fbe21156fcb55db6dba3fb329daae24f0fba3d Author: Andreas Schneider <a...@samba.org> Date: Tue Jun 27 12:02:30 2023 +0200 tests(cmake): Fix handling of LFS support Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 72d3b3c26a51024e35f82673f6d7ce734ccf54bf Author: Andreas Schneider <a...@samba.org> Date: Fri Jun 23 13:50:03 2023 +0200 tests: Implement test_fcntl_lock correctly This does: openat(AT_FDCWD, "/tmp/test_socket_wrapper_Win6aA/file", O_RDWR|O_CREAT, 0600) = 3 fcntl(3, F_OFD_SETLK, {l_type=F_WRLCK, l_whence=SEEK_SET, l_start=0, l_len=1}) = 0 write(3, "fd=3\n", 5) = 5 fcntl(3, F_OFD_SETLK, {l_type=F_UNLCK, l_whence=SEEK_SET, l_start=0, l_len=1}) = 0 unlink("/tmp/test_socket_wrapper_Win6aA/file") = 0 close(3) close(3) = 0 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit bbe14cc3200ca553b13ed49357e2e88ba487eeaa Author: Andreas Schneider <a...@samba.org> Date: Tue Jun 27 12:18:53 2023 +0200 swrap: Make sure we do not redirect (f)open(at)() or fcntl() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 70ecbaaac38dd47d1b3343ae828a3a7b9ab980c2 Author: Andreas Schneider <a...@samba.org> Date: Tue Jun 27 12:01:46 2023 +0200 tests: Do not build test_swrap_unit with LFS support Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: .gitlab-ci.yml | 20 ++++++++ config.h.cmake | 1 + src/socket_wrapper.c | 129 ++++++++++++++++++++++++++++++++++++++++-------- tests/CMakeLists.txt | 21 ++++++-- tests/test_fcntl_lock.c | 46 ++++++++++++----- 5 files changed, 182 insertions(+), 35 deletions(-) Changeset truncated at 500 lines: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef98aeb..3643167 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,7 @@ variables: TUMBLEWEED_BUILD: buildenv-tumbleweed MINGW_BUILD: buildenv-mingw UBUNTU_BUILD: buildenv-ubuntu + UBUNTU32_BUILD: buildenv-ubuntu32 stages: - build @@ -307,3 +308,22 @@ ubuntu/x86_64: when: on_failure paths: - obj/ + +ubuntu/x86: + stage: test + image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$UBUNTU32_BUILD + script: + - mkdir -p obj && cd obj && cmake + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DPICKY_DEVELOPER=ON + -DUNIT_TESTING=ON .. && + make -j$(nproc) && ctest --output-on-failure + tags: + - shared + except: + - tags + artifacts: + expire_in: 1 week + when: on_failure + paths: + - obj/ diff --git a/config.h.cmake b/config.h.cmake index 399013e..3a5843a 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -45,6 +45,7 @@ #cmakedefine HAVE_OPEN64 1 #cmakedefine HAVE_OPENAT64 1 #cmakedefine HAVE_FOPEN64 1 +#cmakedefine HAVE_FCNTL64 1 #cmakedefine HAVE_GETPROGNAME 1 #cmakedefine HAVE_GETEXECNAME 1 #cmakedefine HAVE_PLEDGE 1 diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index dc07b53..c759d35 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -44,6 +44,12 @@ #include "config.h" +/* + * Make sure we do not redirect (f)open(at)() or fcntl() to their 64bit + * variants + */ +#undef _FILE_OFFSET_BITS + #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> @@ -94,6 +100,10 @@ #include "socket_wrapper.h" +#ifdef __USE_FILE_OFFSET64 +#error -D_FILE_OFFSET_BITS=64 should not be set for socket_wrapper! +#endif + enum swrap_dbglvl_e { SWRAP_LOG_ERROR = 0, SWRAP_LOG_WARN, @@ -507,6 +517,9 @@ typedef int (*__libc_connect)(int sockfd, typedef int (*__libc_dup)(int fd); typedef int (*__libc_dup2)(int oldfd, int newfd); typedef int (*__libc_fcntl)(int fd, int cmd, ...); +#ifdef HAVE_FCNTL64 +typedef int (*__libc_fcntl64)(int fd, int cmd, ...); +#endif typedef FILE *(*__libc_fopen)(const char *name, const char *mode); #ifdef HAVE_FOPEN64 typedef FILE *(*__libc_fopen64)(const char *name, const char *mode); @@ -614,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 @@ -988,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, @@ -1450,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 @@ -4625,6 +4636,7 @@ static FILE *swrap_fopen(const char *name, const char *mode) return fp; } +#undef fopen /* Needed for LFS handling */ FILE *fopen(const char *name, const char *mode) { return swrap_fopen(name, mode); @@ -4676,6 +4688,7 @@ static int swrap_vopen(const char *pathname, int flags, va_list ap) return ret; } +#undef open /* Needed for LFS handling */ int open(const char *pathname, int flags, ...) { va_list ap; @@ -4781,6 +4794,7 @@ static int swrap_vopenat(int dirfd, const char *path, int flags, va_list ap) return ret; } +#undef openat /* Needed for LFS handling */ int openat(int dirfd, const char *path, int flags, ...) { va_list ap; @@ -8505,6 +8519,7 @@ static int swrap_vfcntl(int fd, int cmd, va_list va) return rc; } +#undef fcntl /* Needed for LFS handling */ int fcntl(int fd, int cmd, ...) { va_list va; @@ -8519,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 ***************************/ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 17d8d3c..eb9708b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -71,7 +71,6 @@ set(SWRAP_TESTS test_echo_udp_sendto_recvfrom test_echo_udp_send_recv test_echo_udp_sendmsg_recvmsg - test_swrap_unit test_max_sockets test_public_functions test_close_failure @@ -128,8 +127,16 @@ function(ADD_CMOCKA_TEST_ENVIRONMENT _TEST_NAME) endfunction() if (CMAKE_SIZEOF_VOID_P EQUAL 4) - message(STATUS "Enabling large file support for tests") - set(LFS_CFLAGS "-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64") + execute_process( + COMMAND getconf LFS_CFLAGS + OUTPUT_VARIABLE GETCONF_LFS_CFLAGS + OUTPUT_STRIP_TRAILING_WHITESPACE) + # Create a list from the string + set(LFS_CFLAGS) + if (GETCONF_LFS_CFLAGS) + string(REPLACE " " ";" LFS_CFLAGS ${GETCONF_LFS_CFLAGS}) + endif() + message(STATUS "Enabling large file support for tests: ${LFS_CFLAGS}") endif() foreach(_SWRAP_TEST ${SWRAP_TESTS}) @@ -167,6 +174,14 @@ if (HELGRIND_TESTING) endif() endif() +# test_swrap_unit (don't use LFS) +add_cmocka_test(test_swrap_unit + SOURCES test_swrap_unit.c + COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} -D_GNU_SOURCE + LINK_LIBRARIES ${TORTURE_LIBRARY} socket_wrapper_noop + LINK_OPTIONS ${DEFAULT_LINK_FLAGS}) +add_cmocka_test_environment(test_swrap_unit) + # test_fork_pthread add_library(thread_deadlock SHARED thread_deadlock.c) target_link_libraries(thread_deadlock ${CMAKE_THREAD_LIBS_INIT}) diff --git a/tests/test_fcntl_lock.c b/tests/test_fcntl_lock.c index 6bf2cd1..0c172d6 100644 --- a/tests/test_fcntl_lock.c +++ b/tests/test_fcntl_lock.c @@ -49,34 +49,56 @@ static int teardown(void **state) static void test_fcntl_lock(void **state) { char file[PATH_MAX]; - int fd, rc; - struct flock lock; + char buf[16]; + int fd, rc, len; char *s = (char *)*state; + struct flock lock = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 1, + }; int cmd = F_SETLK; -#ifdef F_SETLK64 - cmd = F_SETLK64; -#endif + +/* Prefer OFD locks on Linux with _GNU_SOURCE set */ #ifdef F_OFD_SETLK - cmd = F_OFD_SETLK; + if (sizeof(lock) >= 24) { + cmd = F_OFD_SETLK; + } +#endif + + printf("sizeof(lock)=%zu\n", sizeof(lock)); +#ifdef __USE_LARGEFILE64 + printf("__USE_LARGEFILE64\n"); +#endif +#ifdef __USE_FILE_OFFSET64 + printf("__USE_FILE_OFFSET64\n"); #endif rc = snprintf(file, sizeof(file), "%s/file", s); assert_in_range(rc, 0, PATH_MAX); - fd = open(file, O_CREAT, 0600); + fd = open(file, O_RDWR|O_CREAT, 0600); assert_return_code(fd, errno); - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 4; - lock.l_pid = 0; + rc = fcntl(fd, cmd, &lock); + assert_return_code(rc, errno); + len = snprintf(buf, sizeof(buf), "fd=%d\n", fd); + assert_in_range(len, 0, sizeof(buf)); + + rc = write(fd, buf, len); + assert_return_code(rc, errno); + + lock.l_type = F_UNLCK; rc = fcntl(fd, cmd, &lock); assert_return_code(rc, errno); rc = unlink(file); assert_return_code(rc, errno); + + rc = close(fd); + assert_return_code(rc, errno); } -- Socket Wrapper Repository