From 068385c951c0608edec6264d55ba9c4c923acccc Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Dec 2019 15:31:35 +0100 Subject: [PATCH 1/6] Problem: internal reimplementation of strlcpy used by default on Linux Solution: use libbsd by default when available, and the internal implementation only as a fallback, to take advantage of Linux distros maintenance of the string libraries. --- CMakeLists.txt | 21 ++++++++++++-- Makefile.am | 12 ++++---- builds/cmake/platform.hpp.in | 1 + configure.ac | 51 ++++++++++++++++++++++++--------- packaging/debian/control | 2 ++ packaging/debian/zeromq.dsc.obs | 2 +- packaging/redhat/zeromq.spec | 2 +- src/ws_engine.cpp | 4 ++- 8 files changed, 71 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba0cab25..f42897f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,25 @@ if (NOT DISABLE_WS) endif() endif() +if(NOT MSVC) + find_package(PkgConfig) + option(WITH_LIBBSD "Use libbsd instead of builtin strlcpy" ON) + if (WITH_LIBBSD) + pkg_check_modules(LIBBSD "libbsd") + if (LIBBSD_FOUND) + message(STATUS "Using libbsd") + include_directories(${LIBBSD_INCLUDE_DIRS}) + set(pkg_config_names_private "${pkg_config_names_private} libbsd") + set(ZMQ_HAVE_LIBBSD 1) + link_directories(${LIBBSD_LIBRARY_DIRS}) + set(OPTIONAL_LIBRARIES ${LIBBSD_LIBRARIES}) + endif() + endif() + if (NOT WITH_LIBBSD OR NOT LIBBSD_FOUND) + check_cxx_symbol_exists(strlcpy string.h ZMQ_HAVE_STRLCPY) + endif() +endif() + # Select curve encryption library, defaults to tweetnacl # To use libsodium instead, use --with-libsodium(must be installed) @@ -460,7 +479,6 @@ if(NOT MSVC) check_cxx_symbol_exists(mkdtemp stdlib.h HAVE_MKDTEMP) check_cxx_symbol_exists(accept4 sys/socket.h HAVE_ACCEPT4) check_cxx_symbol_exists(strnlen string.h HAVE_STRNLEN) - check_cxx_symbol_exists(strlcpy string.h ZMQ_HAVE_STRLCPY) else() set(HAVE_STRNLEN 1) endif() @@ -661,7 +679,6 @@ else() "Name pkg-config shall use to find openpgm libraries and include paths" FORCE) - find_package(PkgConfig) pkg_check_modules(OPENPGM ${OPENPGM_PKGCONFIG_NAME}) if(OPENPGM_FOUND) diff --git a/Makefile.am b/Makefile.am index f4591852..dc718b30 100644 --- a/Makefile.am +++ b/Makefile.am @@ -344,11 +344,11 @@ if HAVE_VSCRIPT_COMPLEX src_libzmq_la_LDFLAGS += $(VSCRIPT_LDFLAGS),$(srcdir)/src/libzmq.vers endif -src_libzmq_la_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) $(LIBUNWIND_CFLAGS) -src_libzmq_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) $(LIBUNWIND_CFLAGS) +src_libzmq_la_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) $(LIBUNWIND_CFLAGS) $(LIBBSD_CFLAGS) +src_libzmq_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) $(LIBUNWIND_CFLAGS) $(LIBBSD_CFLAGS) src_libzmq_la_CXXFLAGS = @LIBZMQ_EXTRA_CXXFLAGS@ $(CODE_COVERAGE_CXXFLAGS) \ - $(LIBUNWIND_CFLAGS) -src_libzmq_la_LIBADD = $(CODE_COVERAGE_LDFLAGS) $(LIBUNWIND_LIBS) + $(LIBUNWIND_CFLAGS) $(LIBBSD_CFLAGS) +src_libzmq_la_LIBADD = $(CODE_COVERAGE_LDFLAGS) $(LIBUNWIND_LIBS) $(LIBBSD_LIBS) if USE_NSS src_libzmq_la_CPPFLAGS += ${NSS3_CFLAGS} @@ -841,10 +841,10 @@ tests_test_security_curve_SOURCES += \ endif tests_test_security_curve_LDADD = \ - ${TESTUTIL_LIBS} src/libzmq.la $(LIBUNWIND_LIBS) + ${TESTUTIL_LIBS} src/libzmq.la $(LIBUNWIND_LIBS) $(LIBBSD_LIBS) tests_test_security_curve_CPPFLAGS = \ ${TESTUTIL_CPPFLAGS} \ - ${LIBUNWIND_CFLAGS} + ${LIBUNWIND_CFLAGS} ${LIBBSD_CFLAGS} if USE_LIBSODIUM tests_test_security_curve_CPPFLAGS += \ diff --git a/builds/cmake/platform.hpp.in b/builds/cmake/platform.hpp.in index a95d9d94..dd0de157 100644 --- a/builds/cmake/platform.hpp.in +++ b/builds/cmake/platform.hpp.in @@ -52,6 +52,7 @@ #cmakedefine HAVE_ACCEPT4 #cmakedefine HAVE_STRNLEN #cmakedefine ZMQ_HAVE_STRLCPY +#cmakedefine ZMQ_HAVE_LIBBSD #cmakedefine ZMQ_HAVE_IPC diff --git a/configure.ac b/configure.ac index 43a74250..4f4509f3 100644 --- a/configure.ac +++ b/configure.ac @@ -751,19 +751,44 @@ AC_COMPILE_IFELSE( AC_MSG_RESULT([no]) ]) -# string.h doesn't seem to be included by default in Fedora 30 -AC_MSG_CHECKING([whether strlcpy is available]) -AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[char buf [100]; size_t bar = strlcpy (buf, "foo", 100); (void)bar; return 0;]]) - ],[ - AC_MSG_RESULT([yes]) - AC_DEFINE(ZMQ_HAVE_STRLCPY, [1], - [strlcpy is available]) - ],[ - AC_MSG_RESULT([no]) -]) +AC_ARG_ENABLE([libbsd], + [AS_HELP_STRING([--enable-libbsd], + [enable libbsd [default=auto]])], + [enable_libbsd=$enableval], + [enable_libbsd="auto"]) + +if test "x$enable_libbsd" != "xno"; then + PKG_CHECK_MODULES(LIBBSD, [libbsd], + [ + AC_DEFINE(ZMQ_HAVE_LIBBSD, 1, [The libbsd library is to be used]) + AC_SUBST([LIBBSD_CFLAGS]) + AC_SUBST([LIBBSD_LIBS]) + PKGCFG_NAMES_PRIVATE="$PKGCFG_NAMES_PRIVATE libbsd" + found_libbsd="yes" + ], + [ + found_libbsd="no" + if test "x$enable_libbsd" = "xyes"; then + AC_MSG_ERROR([Cannot find libbsd]) + else + AC_MSG_WARN([Cannot find libbsd]) + fi + ]) +fi +if test "x$found_libbsd" != "xyes"; then + AC_MSG_CHECKING([whether strlcpy is available]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[char buf [100]; size_t bar = strlcpy (buf, "foo", 100); (void)bar; return 0;]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE(ZMQ_HAVE_STRLCPY, [1], + [strlcpy is available]) + ],[ + AC_MSG_RESULT([no]) + ]) +fi # pthread_setname is non-posix, and there are at least 4 different implementations AC_MSG_CHECKING([whether signature of pthread_setname_np() has 1 argument]) diff --git a/packaging/debian/control b/packaging/debian/control index 066b440f..23c86a6d 100644 --- a/packaging/debian/control +++ b/packaging/debian/control @@ -11,6 +11,7 @@ Build-Depends: debhelper (>= 9), libunwind-dev | libunwind8-dev | libunwind7-dev, libnss3-dev, libgnutls28-dev | libgnutls-dev, + libbsd-dev, pkg-config, asciidoc-base | asciidoc, xmlto, Standards-Version: 3.9.8 @@ -42,6 +43,7 @@ Depends: libzmq5 (= ${binary:Version}), ${misc:Depends}, libunwind-dev | libunwind8-dev | libunwind7-dev, libnss3-dev, libgnutls28-dev | libgnutls-dev, + libbsd-dev, Conflicts: libzmq-dev, libzmq5-dev Replaces: libzmq5-dev Provides: libzmq5-dev diff --git a/packaging/debian/zeromq.dsc.obs b/packaging/debian/zeromq.dsc.obs index c25d7cde..eeba17df 100644 --- a/packaging/debian/zeromq.dsc.obs +++ b/packaging/debian/zeromq.dsc.obs @@ -6,7 +6,7 @@ Version: 4.3.3 Maintainer: libzmq Developers Homepage: http://www.zeromq.org/ Standards-Version: 3.9.8 -Build-Depends: debhelper (>= 9), dh-autoreconf, libkrb5-dev, libpgm-dev, libnorm-dev, libsodium-dev, libunwind-dev | libunwind8-dev | libunwind7-dev, libnss3-dev, libgnutls28-dev | libgnutls-dev, pkg-config, asciidoc-base | asciidoc, xmlto +Build-Depends: debhelper (>= 9), dh-autoreconf, libkrb5-dev, libpgm-dev, libnorm-dev, libsodium-dev, libunwind-dev | libunwind8-dev | libunwind7-dev, libnss3-dev, libgnutls28-dev | libgnutls-dev, libbsd-dev, pkg-config, asciidoc-base | asciidoc, xmlto Package-List: libzmq3-dev deb libdevel optional arch=any libzmq5 deb libs optional arch=any diff --git a/packaging/redhat/zeromq.spec b/packaging/redhat/zeromq.spec index 0b00cb68..64600e66 100644 --- a/packaging/redhat/zeromq.spec +++ b/packaging/redhat/zeromq.spec @@ -19,7 +19,7 @@ URL: http://www.zeromq.org/ Source: http://download.zeromq.org/%{name}-%{version}.tar.gz Prefix: %{_prefix} Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root -BuildRequires: autoconf automake libtool glib2-devel +BuildRequires: autoconf automake libtool glib2-devel libbsd-devel %if ! (0%{?fedora} > 12 || 0%{?rhel} > 5) BuildRequires: e2fsprogs-devel BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) diff --git a/src/ws_engine.cpp b/src/ws_engine.cpp index 62a92486..70977365 100644 --- a/src/ws_engine.cpp +++ b/src/ws_engine.cpp @@ -74,7 +74,9 @@ along with this program. If not, see . #ifdef ZMQ_HAVE_WINDOWS #define strcasecmp _stricmp #else -#ifndef ZMQ_HAVE_STRLCPY +#ifdef ZMQ_HAVE_LIBBSD +#include +#elif !defined(ZMQ_HAVE_STRLCPY) static size_t strlcpy (char *dest_, const char *src_, const size_t dest_size_) { size_t remain = dest_size_; From 2c2ff01e8562c870efbf5ffb1a3e4ba24a1ade83 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Dec 2019 15:37:07 +0100 Subject: [PATCH 2/6] Problem: CMake does not look for NSS using pkg-config Solution: use pkg-config by default and FindPackage only as a fallback --- CMakeLists.txt | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f42897f4..e42de5fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,8 @@ include(TestZMQVersion) include(ZMQSourceRunChecks) include(ZMQSupportMacros) +find_package(PkgConfig) + option(ENABLE_ASAN "Build with address sanitizer" OFF) if(ENABLE_ASAN) message(STATUS "Instrumenting with Address Sanitizer") @@ -120,17 +122,23 @@ if (NOT DISABLE_WS) set(ZMQ_HAVE_WS 1) if (WITH_NSS) - find_package("NSS3") + pkg_check_modules(NSS3 "nss") if (NSS3_FOUND) - message(STATUS "Using NSS") - include_directories(${NSS3_INCLUDE_DIRS}) - set(pkg_config_names_private "${pkg_config_names_private} nss3") - set(pkg_config_libs_private "${pkg_config_libs_private} -lnss3") - set(ZMQ_USE_NSS 1) + set(pkg_config_names_private "${pkg_config_names_private} nss") else() - message(FATAL_ERROR - "nss is not installed. Install it, then run CMake again") + find_package("NSS3") + if (NSS3_FOUND) + set(pkg_config_libs_private "${pkg_config_libs_private} -lnss3") + else() + message(FATAL_ERROR + "nss is not installed. Install it, then run CMake again") + endif() endif() + message(STATUS "Using NSS") + include_directories(${NSS3_INCLUDE_DIRS}) + link_directories(${NSS3_LIBRARY_DIRS}) + set(OPTIONAL_LIBRARIES ${NSS3_LIBRARIES}) + set(ZMQ_USE_NSS 1) else() list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/external/sha1/sha1.c ${CMAKE_CURRENT_SOURCE_DIR}/external/sha1/sha1.h) message("Using builtin sha1") @@ -139,7 +147,6 @@ if (NOT DISABLE_WS) endif() if(NOT MSVC) - find_package(PkgConfig) option(WITH_LIBBSD "Use libbsd instead of builtin strlcpy" ON) if (WITH_LIBBSD) pkg_check_modules(LIBBSD "libbsd") From 9d2899af877fc36b463847054fc040ac63740bed Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Dec 2019 15:47:23 +0100 Subject: [PATCH 3/6] Problem: libzmq.pc does not include gnutls dependency for static linking Solution: add it to the Requires.private list --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 4f4509f3..8ac65888 100644 --- a/configure.ac +++ b/configure.ac @@ -576,6 +576,7 @@ AC_ARG_WITH([tls], if test "x$enable_ws" != "xno"; then if test "x$with_tls" = "xyes"; then PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.1.4], [ + PKGCFG_NAMES_PRIVATE="$PKGCFG_NAMES_PRIVATE gnutls >= 3.1.4" ws_crypto_library="gnutls" AC_DEFINE(ZMQ_USE_GNUTLS, [1], [Use GNUTLS for TLS]) AC_DEFINE(ZMQ_HAVE_WS, [1], [Using websocket]) From 21f763c872606410aad4289d9915495c77b599ca Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Dec 2019 16:32:46 +0100 Subject: [PATCH 4/6] Problem: libbsd not used on Travis Solution: add it to one build to exercise all the code paths --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 56e717ab..1d05c56a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -92,6 +92,7 @@ matrix: - libpgm-dev - libsodium-dev - libnss3-dev + - libbsd-dev - env: BUILD_TYPE=default CURVE=libsodium DRAFT=enabled os: osx - env: BUILD_TYPE=default CURVE=tweetnacl DRAFT=enabled ADDRESS_SANITIZER=enabled From 3832bd6b11d92b618ae8fdc1f8599ecb2c357e3e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Dec 2019 19:21:57 +0100 Subject: [PATCH 5/6] Problem: UWP build fails Solution: initialize local variable in all cases to false positive compiler warning --- src/ws_engine.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ws_engine.cpp b/src/ws_engine.cpp index 70977365..a8e6e074 100644 --- a/src/ws_engine.cpp +++ b/src/ws_engine.cpp @@ -148,8 +148,11 @@ void zmq::ws_engine_t::start_ws_handshake () else if (_options.mechanism == ZMQ_CURVE) protocol = "ZWS2.0/CURVE"; #endif - else + else { + // Avoid unitialized variable error breaking UWP build + protocol = ""; assert (false); + } unsigned char nonce[16]; int *p = reinterpret_cast (nonce); From c560a414738b3e30ac8128733988c823e3542ff7 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 28 Dec 2019 19:23:18 +0100 Subject: [PATCH 6/6] Problem: mingw build broken Solution: check correct preprocessor define in test_reconnect_ivl to match the test invocation --- tests/test_reconnect_ivl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_reconnect_ivl.cpp b/tests/test_reconnect_ivl.cpp index 8044abcb..51be3368 100644 --- a/tests/test_reconnect_ivl.cpp +++ b/tests/test_reconnect_ivl.cpp @@ -101,7 +101,7 @@ int main (void) setup_test_environment (); UNITY_BEGIN (); -#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_GNU) +#if defined(ZMQ_HAVE_IPC) && !defined(ZMQ_HAVE_GNU) RUN_TEST (test_reconnect_ivl_ipc); #endif RUN_TEST (test_reconnect_ivl_tcp_ipv4);