diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..050f5a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libqb-1.0.3.tar.xz diff --git a/.libqb.metadata b/.libqb.metadata new file mode 100644 index 0000000..fc301d0 --- /dev/null +++ b/.libqb.metadata @@ -0,0 +1 @@ +5e45fd90b9468747577460bc7c28d9e4cf709b9d SOURCES/libqb-1.0.3.tar.xz diff --git a/SOURCES/bz1615945-remove-linker-callsites.patch b/SOURCES/bz1615945-remove-linker-callsites.patch new file mode 100644 index 0000000..0817a02 --- /dev/null +++ b/SOURCES/bz1615945-remove-linker-callsites.patch @@ -0,0 +1,521 @@ +diff -ur libqb-1.0.3/configure.ac libqb-1.0.3.nosection/configure.ac +--- libqb-1.0.3/configure.ac 2017-12-21 09:02:11.000000000 +0000 ++++ libqb-1.0.3.nosection/configure.ac 2018-08-16 10:24:25.425174367 +0100 +@@ -644,139 +644,6 @@ + AM_CONDITIONAL(HAVE_SLOW_TESTS, [test "x${enable_slow_tests}" = xyes]) + AC_SUBST(HAVE_SLOW_TESTS) + +-# --- callsite sections --- +-if test "x${GCC}" = xyes; then +- AX_SAVE_FLAGS +- AC_MSG_CHECKING([whether GCC supports __attribute__((section()) + ld supports orphan sections]) +- if test "x${ac_cv_link_attribute_section}" = x ; then +- LDFLAGS="${LDFLAGS_save} -shared -fPIC" # we are compiling shared lib +- AC_LINK_IFELSE( +- [AC_LANG_SOURCE( +- [[#include +- extern int __start___verbose[], __stop___verbose[]; +- int test(void) { +- static int my_var __attribute__((section("__verbose"))) = 3; +- assert("L:non-empty data section" +- && __start___verbose != __stop___verbose); +- assert("L:no data section value loss" +- && my_var == 3 /* for 2.29.1+ */); +- return *((int *) __start___verbose); }]] +- )], +- [gcc_has_attribute_section=yes; cp "conftest${ac_exeext}" "conftest.so"], +- [gcc_has_attribute_section=no] +- ) +- AX_RESTORE_FLAGS +- else +- gcc_has_attribute_section=${ac_cv_link_attribute_section} +- fi +- AC_MSG_RESULT($gcc_has_attribute_section) +- +- # in the failing case (e.g. with ld from binutils 2.29), it's likely the +- # following will fail readily in linkage (hidden symbol `__stop___verbose' +- # in conftest is referenced by DSO), but keep the sensible test +- # (in-executable symbol is expected to be propagated into the library, +- # and to draw the full circle back to the executable through standard +- # return value passing (respectively no-exec probing to spot the issue); +- # -rpath passed because LD_LIBRARY_PATH exporting is unwieldy here); +- # moreover, "my_var" == 3 assertion above (respectively checking if the +- # boundary symbol visibility differs from DEFAULT in readelf output) is +- # necessary so that binutils 2.29.1+ will not slip other parts of the +- # overall is-workaround-needed harness, as it restored some (but not +- # all) of the original behaviour, but the workaround is still provably +- # needed +- if test "x${gcc_has_attribute_section}" = xyes; then +- AC_MSG_CHECKING([whether linker emits global boundary symbols for orphan sections]) +- LIBS="${LIBS} -L. -l:conftest${shrext_cmds} -Wl,-rpath=$(pwd)" +- dnl could be turned to AC_TRY_RUN (first assertion is equivalent to +- dnl the further check in action-if-true), but that would prevent +- dnl cross-building +- AC_LINK_IFELSE( +- [AC_LANG_PROGRAM( +- [[#include +- extern int __start___verbose[], __stop___verbose[]; +- int test(void);]], +- [[static int my_var __attribute__((section("__verbose"))) = 5; +- assert("E:non-empty data section" +- && __start___verbose != __stop___verbose); +- assert("E:no data section value loss" +- && my_var == test() /*5?*/);]] +- )], +- [# alternatively something like (but requires number parsing): +- # readelf -SW "conftest${ac_exeext}" \ +- # | sed -n '/__verbose/s/^\s*//p' | tr -s ' ' | cut -d" " -f6 +- verbose_start_addr=$(${NM} -g --portability -- "conftest${ac_exeext}" \ +- | grep __start___verbose | cut -d" " -f 3) +- verbose_stop_addr=$(${NM} -g --portability -- "conftest${ac_exeext}" \ +- | grep __stop___verbose | cut -d" " -f 3) +- test "${verbose_start_addr}" = "${verbose_stop_addr}" \ +- && gcc_has_attribute_section_visible=no \ +- || { verbose_start_type=$(${READELF} -s backup \ +- | sed -n '/__start___verbose/{s/^\s*//p;q}' \ +- | tr -s ' ' \ +- | cut -d" " -f6) +- test "${verbose_start_type}" = DEFAULT \ +- && gcc_has_attribute_section_visible=yes \ +- || gcc_has_attribute_section_visible=no; }], +- [gcc_has_attribute_section_visible=no] +- ) +- AX_RESTORE_FLAGS +- AC_MSG_RESULT($gcc_has_attribute_section_visible) +- rm -f "conftest${shrext_cmds}" +- +- if test "x${gcc_has_attribute_section_visible}" = xno; then +- # check if the linker script based workaround is +- # feasible at all, otherwise fallback to using no +- # section attribute while making some noise about it +- # as combining with-without accustomed logging +- # participants is currently uncharted waters +- AC_MSG_CHECKING([whether linker workaround for orphan sections usable]) +- >conftest.ld cat <<-EOF +- SECTIONS { +- __verbose : { +- __start___verbose = .; +- *(__verbose); +- __stop___verbose = .; +- } +- } +- EOF +- LDFLAGS="${LDFLAGS} -Wl,conftest.ld" +- AC_LINK_IFELSE( +- [AC_LANG_PROGRAM( +- [[#include +- extern int __start___verbose[], __stop___verbose[]; +- int test(void);]], +- [[static int my_var __attribute__((section("__verbose"))) = 5; +- assert("E:non-empty data section" +- && __start___verbose != __stop___verbose); +- assert("E:no data section value loss" +- && my_var == 5);]] +- )], +- [], +- [gcc_has_attribute_section=no] +- ) +- AX_RESTORE_FLAGS +- AC_MSG_RESULT([$gcc_has_attribute_section]) +- rm -f "conftest.ld" +- fi +- +- if test "x${gcc_has_attribute_section}" = xyes; then +- AC_DEFINE([QB_HAVE_ATTRIBUTE_SECTION], 1, +- [Enabling code using __attribute__((section))]) +- AC_SUBST([client_dlopen_LIBS],[$dlopen_LIBS]) +- if test "x${gcc_has_attribute_section_visible}" = xyes; then +- PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section" +- else +- AC_DEFINE([QB_NEED_ATTRIBUTE_SECTION_WORKAROUND], 1, +- [Enabling code using __attribute__((section))]) +- PACKAGE_FEATURES="$PACKAGE_FEATURES attribute-section-workaround" +- fi +- elif test "x${enable_nosection_fallback}" = xyes; then +- AC_MSG_NOTICE([Falling back to not using orphan section]) +- else +- AC_MSG_ERROR([Would use section attribute, cannot; see --enable-nosection-fallback]) +- fi +- fi +-fi + AM_CONDITIONAL(HAVE_GCC_ATTRIBUTE_SECTION, [test "x${gcc_has_attribute_section}" = xyes]) + AM_CONDITIONAL(NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND, + [test "x${gcc_has_attribute_section}" = xyes \ +diff -ur libqb-1.0.3/include/qb/qbconfig.h.in libqb-1.0.3.nosection/include/qb/qbconfig.h.in +--- libqb-1.0.3/include/qb/qbconfig.h.in 2017-12-14 09:25:16.000000000 +0000 ++++ libqb-1.0.3.nosection/include/qb/qbconfig.h.in 2018-08-16 10:23:15.018923879 +0100 +@@ -27,9 +27,6 @@ + /* need atomic memory barrier */ + #undef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED + +-/* Enabling code using __attribute__((section)) */ +-#undef QB_HAVE_ATTRIBUTE_SECTION +- + /* versioning info: MAJOR, MINOR, MICRO, and REST components; + note that static compile-time info is not that useful as consulting + the respectively named members of qb_version struct constant under +diff -ur libqb-1.0.3/include/qb/qblog.h libqb-1.0.3.nosection/include/qb/qblog.h +--- libqb-1.0.3/include/qb/qblog.h 2017-12-21 09:02:11.000000000 +0000 ++++ libqb-1.0.3.nosection/include/qb/qblog.h 2018-08-16 10:23:15.018923879 +0100 +@@ -39,15 +39,6 @@ + #include + #include + +-#if defined(QB_KILL_ATTRIBUTE_SECTION) || defined(S_SPLINT_S) +-#undef QB_HAVE_ATTRIBUTE_SECTION +-#endif /* defined(QB_KILL_ATTRIBUTE_SECTION) || defined(S_SPLINT_S) */ +- +-#ifdef QB_HAVE_ATTRIBUTE_SECTION +-#include /* possibly needed for QB_LOG_INIT_DATA */ +-#include /* dynamic linking: dlopen, dlsym, dladdr, ... */ +-#endif +- + /** + * @file qblog.h + * The logging API provides four main parts (basics, filtering, threading & blackbox). +@@ -286,119 +277,7 @@ + + typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs); + +-/* will be assigned by linker magic (assuming linker supports that): +- * https://sourceware.org/binutils/docs/ld/Orphan-Sections.html +- */ +-#ifdef QB_HAVE_ATTRIBUTE_SECTION +- +-#define QB_ATTR_SECTION __verbose /* conforms to C ident. */ +-#define QB_ATTR_SECTION_STR QB_PP_STRINGIFY(QB_ATTR_SECTION) +-#define QB_ATTR_SECTION_START QB_PP_JOIN(__start_, QB_ATTR_SECTION) +-#define QB_ATTR_SECTION_STOP QB_PP_JOIN(__stop_, QB_ATTR_SECTION) +-#define QB_ATTR_SECTION_START_STR QB_PP_STRINGIFY(QB_ATTR_SECTION_START) +-#define QB_ATTR_SECTION_STOP_STR QB_PP_STRINGIFY(QB_ATTR_SECTION_STOP) +- +-extern struct qb_log_callsite QB_ATTR_SECTION_START[]; +-extern struct qb_log_callsite QB_ATTR_SECTION_STOP[]; +- +-/* Related to the next macro that is -- unlike this one -- a public API */ +-#ifndef _GNU_SOURCE +-#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \ +- _Pragma(QB_PP_STRINGIFY(GCC warning QB_PP_STRINGIFY( \ +- without "_GNU_SOURCE" defined (directly or not) \ +- QB_LOG_INIT_DATA cannot check sanity of libqb proper \ +- nor of the target site originating this check alone))) +-#else +-#define QB_NONAPI_LOG_INIT_DATA_EXTRA_(name) \ +- { Dl_info work_dli; \ +- /* libqb sanity (locating libqb by it's relatively unique \ +- non-functional symbols -- the two are mutually exclusive, the \ +- ordinarily latter was introduced by accident, the former is \ +- intentional -- due to possible confusion otherwise) */ \ +- if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli) \ +- || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli)) \ +- && (work_handle = dlopen(work_dli.dli_fname, \ +- RTLD_LOCAL|RTLD_LAZY)) != NULL) { \ +- work_s1 = (struct qb_log_callsite *) \ +- dlsym(work_handle, QB_ATTR_SECTION_START_STR); \ +- work_s2 = (struct qb_log_callsite *) \ +- dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \ +- assert("libqb's callsite section is observable, otherwise \ +-libqb's build is at fault, preventing reliable logging" \ +- && work_s1 != NULL && work_s2 != NULL); \ +- assert("libqb's callsite section is populated, otherwise \ +-libqb's build is at fault, preventing reliable logging" \ +- && work_s1 != work_s2); \ +- dlclose(work_handle); } \ +- /* sanity of the target site originating this check alone */ \ +- if (dladdr(dlsym(RTLD_DEFAULT, QB_PP_STRINGIFY(name)), &work_dli) \ +- && (work_handle = dlopen(work_dli.dli_fname, \ +- RTLD_LOCAL|RTLD_LAZY)) != NULL) { \ +- work_s1 = (struct qb_log_callsite *) \ +- dlsym(work_handle, QB_ATTR_SECTION_START_STR); \ +- work_s2 = (struct qb_log_callsite *) \ +- dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \ +- assert("target's own callsite section observable, otherwise \ +-target's own linkage at fault and logging would not work reliably \ +-(unless QB_LOG_INIT_DATA macro used unexpectedly in no-logging context)"\ +- && work_s1 != NULL && work_s2 != NULL); \ +- assert("target's own callsite section non-empty, otherwise \ +-target's own linkage at fault and logging would not work reliably \ +-(unless QB_LOG_INIT_DATA macro used unexpectedly in no-logging context)"\ +- && work_s1 != work_s2); \ +- dlclose(work_handle); } } +-#endif /* _GNU_SOURCE */ +- +-/** +- * Optional on-demand self-check of 1/ toolchain sanity (prerequisite for +- * the logging subsystem to work properly) and 2/ non-void active use of +- * logging (satisfied with a justifying existence of a logging callsite as +- * defined with a @c qb_logt invocation) at the target (but see below), which +- * is supposedly assured by it's author(!) as of relying on this very macro +- * [technically, the symbols that happen to be resolved under the respective +- * identifiers do not necessarily originate in the same compilation unit as +- * when it's not the end executable (or by induction, a library positioned +- * earlier in the symbol lookup order) but a shared library, the former takes +- * a precedence unless that site comes short of exercising the logging, +- * making its callsite section empty and, in turn, without such boundary +- * symbols, hence making the resolution continue further in the lookup order +- * -- despite fuzzily targeted attestation, the check remains reasonable]; +- * only effective when link-time ("run-time amortizing") callsite collection +- * is; as a side effect, it can ensure the boundary-denoting symbols for the +- * target collection area are kept alive with some otherwise unkind linkers. +- * +- * Applying this macro in the target program/library is strongly recommended +- * whenever the logging as framed by this header file is in use. +- * Moreover, it's important to state that using this check while not ensuring +- * @c _GNU_SOURCE macro definition is present at compile-time means only half +- * of the available sanity checking will be performed, possibly resulting +- * in libqb's own internally logged messages being lost without warning. +- */ +-#define QB_LOG_INIT_DATA(name) \ +- void name(void); \ +- void name(void) { \ +- void *work_handle; struct qb_log_callsite *work_s1, *work_s2; \ +- /* our own (target's) sanity, or possibly that of higher priority \ +- symbol resolution site (unless target equals end executable) \ +- or even the lower one if no such predecessor defines these */ \ +- if ((work_handle = dlopen(NULL, RTLD_LOCAL|RTLD_LAZY)) != NULL) { \ +- work_s1 = (struct qb_log_callsite *) \ +- dlsym(work_handle, QB_ATTR_SECTION_START_STR); \ +- work_s2 = (struct qb_log_callsite *) \ +- dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); \ +- assert("implicit callsite section is observable, otherwise \ +-target's and/or libqb's build is at fault, preventing reliable logging" \ +- && work_s1 != NULL && work_s2 != NULL); \ +- dlclose(work_handle); /* perhaps overly eager thing to do */ } \ +- QB_NONAPI_LOG_INIT_DATA_EXTRA_(name); \ +- /* finally, original, straightforward check */ \ +- assert("implicit callsite section is populated, otherwise \ +-target's build is at fault, preventing reliable logging" \ +- && QB_ATTR_SECTION_START != QB_ATTR_SECTION_STOP); } \ +- void __attribute__ ((constructor)) name(void); +-#else + #define QB_LOG_INIT_DATA(name) +-#endif /* QB_HAVE_ATTRIBUTE_SECTION */ + + /** + * Internal function: use qb_log() or qb_logt() +@@ -476,21 +355,12 @@ + * @param fmt usual printf style format specifiers + * @param args usual printf style args + */ +-#ifdef QB_HAVE_ATTRIBUTE_SECTION +-#define qb_logt(priority, tags, fmt, args...) do { \ +- static struct qb_log_callsite descriptor \ +- __attribute__((section(QB_ATTR_SECTION_STR), aligned(8))) = \ +- { __func__, __FILE__, fmt, priority, __LINE__, 0, tags }; \ +- qb_log_real_(&descriptor, ##args); \ +- } while(0) +-#else + #define qb_logt(priority, tags, fmt, args...) do { \ + struct qb_log_callsite* descriptor_pt = \ + qb_log_callsite_get(__func__, __FILE__, fmt, \ + priority, __LINE__, tags); \ + qb_log_real_(descriptor_pt, ##args); \ + } while(0) +-#endif /* QB_HAVE_ATTRIBUTE_SECTION */ + + + /** +--- libqb-1.0.3/lib/libqb.pc.in 2017-12-14 09:25:16.000000000 +0000 ++++ libqb-1.0.3.nosection/lib/libqb.pc.in 2018-08-16 10:23:15.019923883 +0100 +@@ -7,17 +7,6 @@ + Version: @PACKAGE_VERSION@ + Description: libqb + Requires: +-Libs: -L${libdir} -lqb @client_dlopen_LIBS@ +-# NOTE: If -lqb not usable for linking (e.g. linker not compatible with +-# linker scripts ad-hoc modifying output sections), try recent +-# ld.bfd/binutils linker first when available, otherwise you can +-# try "-l:libqb.so." link switch that bypasses said linker +-# script -- but beware, logging may be less efficient and may lack +-# possible future optimizations and extra features. Consequently, +-# logging issues (typically bound to QB_LOG_INIT_DATA macro) can be +-# mitigated with QB_KILL_ATTRIBUTE_SECTION macro defined for a build. +-# NOTE: when concerned about a warning coming from the build process like +-# warning: [...]libqb.so contains output sections; did you forget -T? +-# and the build finishes OK, take it merely as a harmless side-effect ++Libs: -L${libdir} -lqb + Libs.private: @LIBS@ + Cflags: -I${includedir} +diff -ur libqb-1.0.3/lib/log.c libqb-1.0.3.nosection/lib/log.c +--- libqb-1.0.3/lib/log.c 2017-12-21 09:02:11.000000000 +0000 ++++ libqb-1.0.3.nosection/lib/log.c 2018-08-16 10:26:01.465514061 +0100 +@@ -40,13 +40,6 @@ + #include "util_int.h" + #include + +-#if defined(QB_NEED_ATTRIBUTE_SECTION_WORKAROUND) && !defined(S_SPLINT_S) +-/* following only needed to force these symbols be global +- with ld 2.29: https://bugzilla.redhat.com/1477354 */ +-struct qb_log_callsite __attribute__((weak)) QB_ATTR_SECTION_START[] = { {0} }; +-struct qb_log_callsite __attribute__((weak)) QB_ATTR_SECTION_STOP[] = { {0} }; +-#endif +- + static struct qb_log_target conf[QB_LOG_TARGET_MAX]; + static uint32_t conf_active_max = 0; + static int32_t in_logger = QB_FALSE; +@@ -772,73 +765,6 @@ + return qb_log_filter_ctl2(t, c, type, text, LOG_EMERG, priority); + } + +-#ifdef QB_HAVE_ATTRIBUTE_SECTION +-/* Some platforms (eg. FreeBSD 10+) don't support calling dlopen() from +- * within a dl_iterate_phdr() callback; so save all of the dlpi_names to +- * a list and iterate over them afterwards. */ +-static int32_t +-_log_so_walk_callback(struct dl_phdr_info *info, size_t size, void *data) +-{ +- struct dlname *dlname; +- +- if (strlen(info->dlpi_name) > 0) { +- dlname = calloc(1, sizeof(struct dlname)); +- if (!dlname) +- return 0; +- dlname->dln_name = strdup(info->dlpi_name); +- qb_list_add_tail(&dlname->list, &dlnames); +- } +- +- return 0; +-} +- +-static void +-_log_so_walk_dlnames(void) +-{ +- struct dlname *dlname; +- struct qb_list_head *iter; +- struct qb_list_head *next; +- +- void *handle; +- void *start; +- void *stop; +- const char *error; +- +- qb_list_for_each_safe(iter, next, &dlnames) { +- dlname = qb_list_entry(iter, struct dlname, list); +- +- handle = dlopen(dlname->dln_name, RTLD_LAZY); +- error = dlerror(); +- if (!handle || error) { +- qb_log(LOG_ERR, "%s", error); +- goto done; +- } +- +- start = dlsym(handle, QB_ATTR_SECTION_START_STR); +- error = dlerror(); +- if (error) { +- goto done; +- } +- +- stop = dlsym(handle, QB_ATTR_SECTION_STOP_STR); +- error = dlerror(); +- if (error) { +- goto done; +- +- } else { +- qb_log_callsites_register(start, stop); +- } +-done: +- if (handle) +- dlclose(handle); +- qb_list_del(iter); +- if (dlname->dln_name) +- free(dlname->dln_name); +- free(dlname); +- } +-} +-#endif /* QB_HAVE_ATTRIBUTE_SECTION */ +- + static void + _log_target_state_set(struct qb_log_target *t, enum qb_log_target_state s) + { +@@ -864,10 +790,6 @@ + { + int32_t l; + enum qb_log_target_slot i; +-#ifdef QB_HAVE_ATTRIBUTE_SECTION +- void *work_handle; struct qb_log_callsite *work_s1, *work_s2; +- Dl_info work_dli; +-#endif /* QB_HAVE_ATTRIBUTE_SECTION */ + /* cannot reuse single qb_log invocation in various contexts + through the variables (when section attribute in use), + hence this indirection */ +@@ -893,33 +815,6 @@ + } + + qb_log_dcs_init(); +-#ifdef QB_HAVE_ATTRIBUTE_SECTION +- /* sanity check that target chain supplied QB_ATTR_SECTION_ST{ART,OP} +- symbols and hence the local references to them are not referencing +- the proper libqb's ones (locating libqb by it's relatively unique +- non-functional symbols -- the two are mutually exclusive, the +- ordinarily latter was introduced by accident, the former is +- intentional -- due to possible confusion otherwise) */ +- if ((dladdr(dlsym(RTLD_DEFAULT, "qb_ver_str"), &work_dli) +- || dladdr(dlsym(RTLD_DEFAULT, "facilitynames"), &work_dli)) +- && (work_handle = dlopen(work_dli.dli_fname, +- RTLD_LOCAL|RTLD_LAZY)) != NULL) { +- work_s1 = (struct qb_log_callsite *) +- dlsym(work_handle, QB_ATTR_SECTION_START_STR); +- work_s2 = (struct qb_log_callsite *) +- dlsym(work_handle, QB_ATTR_SECTION_STOP_STR); +- if (work_s1 == QB_ATTR_SECTION_START +- || work_s2 == QB_ATTR_SECTION_STOP) { +- preinit_err = preinit_err_target_sec; +- } else if (work_s1 == work_s2) { +- preinit_err = preinit_err_target_empty; +- } +- dlclose(work_handle); /* perhaps overly eager thing to do */ +- } +- qb_log_callsites_register(QB_ATTR_SECTION_START, QB_ATTR_SECTION_STOP); +- dl_iterate_phdr(_log_so_walk_callback, NULL); +- _log_so_walk_dlnames(); +-#endif /* QB_HAVE_ATTRIBUTE_SECTION */ + + for (i = QB_LOG_TARGET_STATIC_START; i < QB_LOG_TARGET_STATIC_MAX; i++) + conf[i].state = QB_LOG_STATE_DISABLED; +diff -ur libqb-1.0.3/lib/Makefile.am libqb-1.0.3.nosection/lib/Makefile.am +--- libqb-1.0.3/lib/Makefile.am 2017-12-14 09:25:16.000000000 +0000 ++++ libqb-1.0.3.nosection/lib/Makefile.am 2018-08-16 10:25:07.001321422 +0100 +@@ -79,9 +79,6 @@ + libqb_la_SOURCES = $(source_to_lint) unix.c + libqb_la_CFLAGS = $(PTHREAD_CFLAGS) + libqb_la_LIBADD = $(LTLIBOBJS) $(dlopen_LIBS) $(PTHREAD_LIBS) $(socket_LIBS) +-if NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND +-libqb_la_LIBADD += qblog_script.la +-endif + + AM_LDFLAGS = $(LDFLAGS_COPY:-Bsymbolic-functions=) + +@@ -110,33 +107,6 @@ + pkgconfigexecdir = $(libdir)/pkgconfig + pkgconfigexec_DATA = libqb.pc + +-# find the libqb.so symlink's target, if so, try to find out, iteratively, +-# its gradually shorter forms that likewise symlinks the same target as the +-# original libqb.so path, point to that file from the linker script using +-# qblog_script.ld as a template, storing result in place of original libqb.so +-# (e.g., libqb.so := "INPUT(libqb.so.0) " [...] "SECTIONS { " [...] "}") +-# NOTE: readlink nor realpath are POSIX; not chained links ready +-# NOTE: conservative check, i.e., not per NEED_GCC_ATTRIBUTE_SECTION_WORKAROUND +-if HAVE_GCC_ATTRIBUTE_SECTION +-install-exec-hook: qblog_script.ld +- target=$$(ls -l "$(DESTDIR)$(libdir)/libqb.so" || :); \ +- target=$${target#* -> }; t1_bn=$$(basename "$${target}" || :); \ +- while test -n "$${t1_bn}"; do t2_bn=$${t1_bn%.*[0-9]*}; \ +- test "$${t2_bn}" != libqb.so || break; \ +- test -L "$${t2_bn}" || { t1_bn=$${t2_bn}; continue; }; \ +- t2_target=$$(ls -l "$${t2_bn}" || break); t2_target=$${t2_target#* -> }; \ +- test "$${t2_target}" = "$${target}" || break; \ +- t1_bn=$${t2_bn}; done; test -n "$${t1_bn}" || \ +- { echo "only applicable to SO symlink scheme"; exit 1; }; \ +- echo "$${t1_bn}" > "$(DESTDIR)$(libdir)/libqb.so-t" +- so_ver=$$(cat "$(DESTDIR)$(libdir)/libqb.so-t"); \ +- echo "INPUT($${so_ver})" > "$(DESTDIR)$(libdir)/libqb.so-t"; \ +- cat $< >> "$(DESTDIR)$(libdir)/libqb.so-t"; \ +- sed -i -- "s/libqb.so./$${so_ver}/" \ +- "$(DESTDIR)$(libdir)/libqb.so-t" "$(DESTDIR)$(pkgconfigexecdir)/libqb.pc" +- mv -f "$(DESTDIR)$(libdir)/libqb.so-t" "$(DESTDIR)$(libdir)/libqb.so" +-endif +- + if HAVE_SPLINT + check_SCRIPTS = run_splint.sh + TESTS = $(check_SCRIPTS) diff --git a/SOURCES/bz1682119-install-tests.patch b/SOURCES/bz1682119-install-tests.patch new file mode 100644 index 0000000..fa611d9 --- /dev/null +++ b/SOURCES/bz1682119-install-tests.patch @@ -0,0 +1,145 @@ +diff -urp libqb-1.0.3.orig/configure.ac libqb-1.0.3/configure.ac +--- libqb-1.0.3.orig/configure.ac 2019-03-19 12:37:55.207208435 +0000 ++++ libqb-1.0.3/configure.ac 2019-03-19 12:38:31.947311047 +0000 +@@ -526,6 +526,17 @@ AC_ARG_WITH([force-sockets-config-file], + [ FORCESOCKETSFILE="$withval" ], + [ FORCESOCKETSFILE="$sysconfdir/libqb/force-filesystem-sockets" ]) + ++AC_ARG_ENABLE([install-tests], ++ [AS_HELP_STRING([--enable-install-tests],[install tests])],, ++ [ enable_install_tests="no" ]) ++AM_CONDITIONAL([INSTALL_TESTS], [test x$enable_install_tests = xyes]) ++ ++AC_ARG_WITH([testdir], ++ [AS_HELP_STRING([--with-testdir=DIR],[path to /usr/lib../libqb/tests/ dir where to install the test suite])], ++ [ TESTDIR="$withval" ], ++ [ TESTDIR="$libdir/libqb/tests" ]) ++AC_SUBST([TESTDIR]) ++ + AC_SUBST(CP) + # *FLAGS handling goes here + +diff -urp libqb-1.0.3.orig/libqb.spec.in libqb-1.0.3/libqb.spec.in +--- libqb-1.0.3.orig/libqb.spec.in 2017-12-14 09:25:16.000000000 +0000 ++++ libqb-1.0.3/libqb.spec.in 2019-03-19 12:38:31.948311049 +0000 +@@ -1,4 +1,5 @@ + %bcond_without check ++%bcond_without testsrpm + + %global alphatag @alphatag@ + %global numcomm @numcomm@ +@@ -26,7 +27,11 @@ and polling. + + %build + ./autogen.sh +-%configure --disable-static ++%configure \ ++%if %{with testsrpm} ++ --enable-install-tests \ ++%endif ++ --disable-static + make %{?_smp_mflags} + + %if 0%{?with_check} +@@ -67,6 +72,20 @@ developing applications that use %{name} + %{_libdir}/pkgconfig/libqb.pc + %{_mandir}/man3/qb*3* + ++%if %{with testsrpm} ++%package tests ++Summary: Test suite for %{name} ++Group: Development/Libraries ++Requires: %{name}%{?_isa} = %{version}-%{release} ++ ++%files tests ++%doc COPYING ++%{_libdir}/libqb/tests/* ++ ++%description tests ++The %{name}-tests package contains the %{name} test suite. ++%endif ++ + %changelog + * @date@ Autotools generated version - @version@-1-@numcomm@.@alphatag@.@dirty@ + - Autotools generated version +diff -urp libqb-1.0.3.orig/tests/blackbox-segfault.sh libqb-1.0.3/tests/blackbox-segfault.sh +--- libqb-1.0.3.orig/tests/blackbox-segfault.sh 2017-11-17 13:31:14.000000000 +0000 ++++ libqb-1.0.3/tests/blackbox-segfault.sh 2019-03-19 12:44:06.650325170 +0000 +@@ -1,25 +1,31 @@ +-#!/bin/sh ++#!/bin/sh ++# ++# Needs PATH to be set to find accompanying test programs ++# - including qb-blackbox which for in-tree tests should be ++# - in ../tools ++ + # + # create a normal blackbox ++# + rm -f crash-test-dummy.fdata +-./crash_test_dummy ++crash_test_dummy ++rm -f core* + +-. ./test.conf ++. test.conf + + # first test that reading the valid + # blackbox data actually works. +-../tools/qb-blackbox crash-test-dummy.fdata ++qb-blackbox crash-test-dummy.fdata + if [ $? -ne 0 ]; then + exit 1 + fi + +- + for i in $(seq $NUM_BB_TESTS) + do + rm -f butchered_blackbox.fdata + echo " ==== Corrupt blackbox test $i/$NUM_BB_TESTS ====" +- ./file_change_bytes -i crash-test-dummy.fdata -o butchered_blackbox.fdata -n 1024 +- ../tools/qb-blackbox butchered_blackbox.fdata ++ file_change_bytes -i crash-test-dummy.fdata -o butchered_blackbox.fdata -n 1024 ++ qb-blackbox butchered_blackbox.fdata + [ $? -gt 127 ] && exit 1 || true + done + +diff -urp libqb-1.0.3.orig/tests/Makefile.am libqb-1.0.3/tests/Makefile.am +--- libqb-1.0.3.orig/tests/Makefile.am 2017-12-14 09:25:16.000000000 +0000 ++++ libqb-1.0.3/tests/Makefile.am 2019-03-19 12:39:40.658511799 +0000 +@@ -23,10 +23,13 @@ CLEANFILES = + + SUBDIRS = functional + ++export SOCKETDIR ++ + AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include + + noinst_PROGRAMS = bmc bmcpt bms rbreader rbwriter \ +- bench-log format_compare_speed loop print_ver ++ bench-log format_compare_speed loop print_ver \ ++ $(check_PROGRAMS) + + noinst_HEADERS = check_common.h + +@@ -107,6 +110,7 @@ EXTRA_DIST += resources.test + EXTRA_DIST += blackbox-segfault.sh + + TESTS = array.test map.test rb.test log.test blackbox-segfault.sh loop.test ipc.test resources.test ++TESTS_ENVIRONMENT = export PATH=.:../tools:$$PATH; + + resources.log: rb.log log.log ipc.log + +@@ -119,6 +123,12 @@ TESTS += util.test + check_PROGRAMS += util.test + endif + ++if INSTALL_TESTS ++testsuitedir = $(TESTDIR) ++testsuite_PROGRAMS = $(check_PROGRAMS) ++testsuite_SCRIPTS = $(dist_check_SCRIPTS) test.conf ++endif ++ + file_change_bytes_SOURCES = file_change_bytes.c + + crash_test_dummy_SOURCES = crash_test_dummy.c $(top_builddir)/include/qb/qblog.h diff --git a/SOURCES/bz1714854-improve-shm-security.patch b/SOURCES/bz1714854-improve-shm-security.patch new file mode 100644 index 0000000..5eff40b --- /dev/null +++ b/SOURCES/bz1714854-improve-shm-security.patch @@ -0,0 +1,238 @@ +diff -rup libqb-1.0.3.orig/lib/ipc_int.h libqb-1.0.3/lib/ipc_int.h +--- libqb-1.0.3.orig/lib/ipc_int.h 2017-11-17 13:31:14.000000000 +0000 ++++ libqb-1.0.3/lib/ipc_int.h 2019-05-30 14:51:44.758129831 +0100 +@@ -160,7 +160,7 @@ enum qb_ipcs_connection_state { + QB_IPCS_CONNECTION_SHUTTING_DOWN, + }; + +-#define CONNECTION_DESCRIPTION (34) /* INT_MAX length + 3 */ ++#define CONNECTION_DESCRIPTION NAME_MAX + + struct qb_ipcs_connection_auth { + uid_t uid; +@@ -207,4 +207,6 @@ int32_t qb_ipc_us_sock_error_is_disconne + + int use_filesystem_sockets(void); + ++void remove_tempdir(const char *name); ++ + #endif /* QB_IPC_INT_H_DEFINED */ +Only in libqb-1.0.3/lib: ipc_int.h.orig +diff -rup libqb-1.0.3.orig/lib/ipcs.c libqb-1.0.3/lib/ipcs.c +--- libqb-1.0.3.orig/lib/ipcs.c 2017-11-17 13:31:14.000000000 +0000 ++++ libqb-1.0.3/lib/ipcs.c 2019-05-30 14:51:44.759129833 +0100 +@@ -642,12 +642,13 @@ qb_ipcs_disconnect(struct qb_ipcs_connec + scheduled_retry = 1; + } + } +- ++ remove_tempdir(c->description); + if (scheduled_retry == 0) { + /* This removes the initial alloc ref */ + qb_ipcs_connection_unref(c); + } + } ++ + } + + static void +diff -rup libqb-1.0.3.orig/lib/ipc_setup.c libqb-1.0.3/lib/ipc_setup.c +--- libqb-1.0.3.orig/lib/ipc_setup.c 2017-11-17 13:31:14.000000000 +0000 ++++ libqb-1.0.3/lib/ipc_setup.c 2019-05-30 14:51:44.759129833 +0100 +@@ -620,6 +620,8 @@ handle_new_connection(struct qb_ipcs_ser + int32_t res2 = 0; + uint32_t max_buffer_size = QB_MAX(req->max_msg_size, s->max_buffer_size); + struct qb_ipc_connection_response response; ++ const char suffix[] = "/qb"; ++ int desc_len; + + c = qb_ipcs_connection_alloc(s); + if (c == NULL) { +@@ -642,8 +644,45 @@ handle_new_connection(struct qb_ipcs_ser + c->auth.gid = c->egid = ugp->gid; + c->auth.mode = 0600; + c->stats.client_pid = ugp->pid; +- snprintf(c->description, CONNECTION_DESCRIPTION, +- "%d-%d-%d", s->pid, ugp->pid, c->setup.u.us.sock); ++ ++#if defined(QB_LINUX) || defined(QB_CYGWIN) ++ desc_len = snprintf(c->description, CONNECTION_DESCRIPTION - sizeof suffix, ++ "/dev/shm/qb-%d-%d-%d-XXXXXX", s->pid, ugp->pid, c->setup.u.us.sock); ++ if (desc_len < 0) { ++ res = -errno; ++ goto send_response; ++ } ++ if (desc_len >= CONNECTION_DESCRIPTION - sizeof suffix) { ++ res = -ENAMETOOLONG; ++ goto send_response; ++ } ++ if (mkdtemp(c->description) == NULL) { ++ res = -errno; ++ goto send_response; ++ } ++ if (chmod(c->description, 0770)) { ++ res = -errno; ++ goto send_response; ++ } ++ /* chown can fail because we might not be root */ ++ (void)chown(c->description, c->auth.uid, c->auth.gid); ++ ++ /* We can't pass just a directory spec to the clients */ ++ memcpy(c->description + desc_len, suffix, sizeof suffix); ++#else ++ desc_len = snprintf(c->description, CONNECTION_DESCRIPTION, ++ "%d-%d-%d", s->pid, ugp->pid, c->setup.u.us.sock); ++ if (desc_len < 0) { ++ res = -errno; ++ goto send_response; ++ } ++ if (desc_len >= CONNECTION_DESCRIPTION) { ++ res = -ENAMETOOLONG; ++ goto send_response; ++ } ++#endif ++ ++ + + if (auth_result == 0 && c->service->serv_fns.connection_accept) { + res = c->service->serv_fns.connection_accept(c, +@@ -864,3 +903,21 @@ retry_accept: + qb_ipcs_uc_recv_and_auth(new_fd, s); + return 0; + } ++ ++void remove_tempdir(const char *name) ++{ ++#if defined(QB_LINUX) || defined(QB_CYGWIN) ++ char dirname[PATH_MAX]; ++ char *slash = strrchr(name, '/'); ++ ++ if (slash && slash - name < sizeof dirname) { ++ memcpy(dirname, name, slash - name); ++ dirname[slash - name] = '\0'; ++ /* This gets called more than it needs to be really, so we don't check ++ * the return code. It's more of a desperate attempt to clean up after ourself ++ * in either the server or client. ++ */ ++ (void)rmdir(dirname); ++ } ++#endif ++} +Only in libqb-1.0.3/lib: ipc_setup.c.orig +diff -rup libqb-1.0.3.orig/lib/ipc_shm.c libqb-1.0.3/lib/ipc_shm.c +--- libqb-1.0.3.orig/lib/ipc_shm.c 2017-11-17 13:31:14.000000000 +0000 ++++ libqb-1.0.3/lib/ipc_shm.c 2019-05-30 14:58:42.582211045 +0100 +@@ -239,6 +239,7 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_co + qb_rb_close(qb_rb_lastref_and_ret(&c->request.u.shm.rb)); + } + } ++ remove_tempdir(c->description); + } + + static int32_t +@@ -285,11 +286,11 @@ qb_ipcs_shm_connect(struct qb_ipcs_servi + qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid); + + snprintf(r->request, NAME_MAX, "%s-request-%s", +- s->name, c->description); ++ c->description, s->name); + snprintf(r->response, NAME_MAX, "%s-response-%s", +- s->name, c->description); ++ c->description, s->name); + snprintf(r->event, NAME_MAX, "%s-event-%s", +- s->name, c->description); ++ c->description, s->name); + + res = qb_ipcs_shm_rb_open(c, &c->request, + r->request); +Only in libqb-1.0.3/lib: ipc_shm.c~ +Only in libqb-1.0.3/lib: ipc_shm.c.orig +Only in libqb-1.0.3/lib: ipc_shm.c.rej +diff -rup libqb-1.0.3.orig/lib/ipc_socket.c libqb-1.0.3/lib/ipc_socket.c +--- libqb-1.0.3.orig/lib/ipc_socket.c 2017-11-17 13:31:14.000000000 +0000 ++++ libqb-1.0.3/lib/ipc_socket.c 2019-05-30 14:51:44.761129838 +0100 +@@ -374,6 +374,10 @@ qb_ipcc_us_disconnect(struct qb_ipcc_con + free(base_name); + } + } ++ ++ /* Last-ditch attempt to tidy up after ourself */ ++ remove_tempdir(c->request.u.us.shared_file_name); ++ + qb_ipcc_us_sock_close(c->event.u.us.sock); + qb_ipcc_us_sock_close(c->request.u.us.sock); + qb_ipcc_us_sock_close(c->setup.u.us.sock); +@@ -765,7 +769,10 @@ qb_ipcs_us_disconnect(struct qb_ipcs_con + c->state == QB_IPCS_CONNECTION_ACTIVE) { + munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE); + unlink(c->request.u.us.shared_file_name); ++ ++ + } ++ remove_tempdir(c->description); + } + + static int32_t +@@ -784,13 +791,13 @@ qb_ipcs_us_connect(struct qb_ipcs_servic + c->request.u.us.sock = c->setup.u.us.sock; + c->response.u.us.sock = c->setup.u.us.sock; + +- snprintf(r->request, NAME_MAX, "qb-%s-control-%s", +- s->name, c->description); +- snprintf(r->response, NAME_MAX, "qb-%s-%s", s->name, c->description); ++ snprintf(r->request, NAME_MAX, "%s-control-%s", ++ c->description, s->name); ++ snprintf(r->response, NAME_MAX, "%s-%s", c->description, s->name); + + fd_hdr = qb_sys_mmap_file_open(path, r->request, + SHM_CONTROL_SIZE, +- O_CREAT | O_TRUNC | O_RDWR); ++ O_CREAT | O_TRUNC | O_RDWR | O_EXCL); + if (fd_hdr < 0) { + res = fd_hdr; + errno = -fd_hdr; +Only in libqb-1.0.3/lib: ipc_socket.c.orig +diff -rup libqb-1.0.3.orig/lib/ringbuffer.c libqb-1.0.3/lib/ringbuffer.c +--- libqb-1.0.3.orig/lib/ringbuffer.c 2017-12-21 09:02:11.000000000 +0000 ++++ libqb-1.0.3/lib/ringbuffer.c 2019-05-30 14:51:44.761129838 +0100 +@@ -155,7 +155,7 @@ qb_rb_open_2(const char *name, size_t si + sizeof(struct qb_ringbuffer_shared_s) + shared_user_data_size; + + if (flags & QB_RB_FLAG_CREATE) { +- file_flags |= O_CREAT | O_TRUNC; ++ file_flags |= O_CREAT | O_TRUNC | O_EXCL; + } + + rb = calloc(1, sizeof(struct qb_ringbuffer_s)); +@@ -166,7 +166,7 @@ qb_rb_open_2(const char *name, size_t si + /* + * Create a shared_hdr memory segment for the header. + */ +- snprintf(filename, PATH_MAX, "qb-%s-header", name); ++ snprintf(filename, PATH_MAX, "%s-header", name); + fd_hdr = qb_sys_mmap_file_open(path, filename, + shared_size, file_flags); + if (fd_hdr < 0) { +@@ -217,7 +217,7 @@ qb_rb_open_2(const char *name, size_t si + * They have to be separate. + */ + if (flags & QB_RB_FLAG_CREATE) { +- snprintf(filename, PATH_MAX, "qb-%s-data", name); ++ snprintf(filename, PATH_MAX, "%s-data", name); + fd_data = qb_sys_mmap_file_open(path, + filename, + real_size, file_flags); +diff -rup libqb-1.0.3.orig/lib/unix.c libqb-1.0.3/lib/unix.c +--- libqb-1.0.3.orig/lib/unix.c 2017-11-17 13:31:14.000000000 +0000 ++++ libqb-1.0.3/lib/unix.c 2019-05-30 14:51:44.761129838 +0100 +@@ -81,7 +81,9 @@ qb_sys_mmap_file_open(char *path, const + (void)strlcpy(path, file, PATH_MAX); + } else { + #if defined(QB_LINUX) || defined(QB_CYGWIN) +- snprintf(path, PATH_MAX, "/dev/shm/%s", file); ++ /* This is only now called when talking to an old libqb ++ where we need to add qb- to the name */ ++ snprintf(path, PATH_MAX, "/dev/shm/qb-%s", file); + #else + snprintf(path, PATH_MAX, "%s/%s", SOCKETDIR, file); + is_absolute = path; diff --git a/SOURCES/bz1718773-avoid-ipc-deadlock.patch b/SOURCES/bz1718773-avoid-ipc-deadlock.patch new file mode 100644 index 0000000..31bcbc6 --- /dev/null +++ b/SOURCES/bz1718773-avoid-ipc-deadlock.patch @@ -0,0 +1,23 @@ +diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c +index 43dc3e7..b3f3412 100644 +--- a/lib/ipc_setup.c ++++ b/lib/ipc_setup.c +@@ -843,12 +843,13 @@ qb_ipcs_uc_recv_and_auth(int32_t sock, struct qb_ipcs_service *s) + setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + #endif + +- res = s->poll_fns.dispatch_add(QB_LOOP_MED, +- data->sock, +- POLLIN | POLLPRI | POLLNVAL, +- data, process_auth); ++ res = s->poll_fns.dispatch_add(s->poll_priority, ++ data->sock, ++ POLLIN | POLLPRI | POLLNVAL, ++ data, process_auth); + if (res < 0) { +- qb_util_log(LOG_DEBUG, "Failed to process AUTH for fd (%d)", data->sock); ++ qb_util_log(LOG_DEBUG, "Failed to arrange for AUTH for fd (%d)", ++ data->sock); + close(sock); + destroy_ipc_auth_data(data); + } diff --git a/SOURCES/bz1836146-covscan-fixes.patch b/SOURCES/bz1836146-covscan-fixes.patch new file mode 100644 index 0000000..c4fbd6d --- /dev/null +++ b/SOURCES/bz1836146-covscan-fixes.patch @@ -0,0 +1,32 @@ +commit bfa90160e5856cd91e7c3e58bfd50387a41b8ca9 +Author: Christine Caulfield +Date: Wed May 20 11:18:07 2020 +0100 + + Some bugs spotted by coverity + +diff --git a/include/tlist.h b/include/tlist.h +index bcae55d..723d3ec 100644 +--- a/include/tlist.h ++++ b/include/tlist.h +@@ -191,7 +191,7 @@ static inline void timerlist_expire(struct timerlist *timerlist) + uint64_t current_time; + + current_monotonic_time = qb_util_nano_current_get(); +- current_time_from_epoch = current_time = qb_util_nano_from_epoch_get(); ++ current_time_from_epoch = qb_util_nano_from_epoch_get(); + + qb_list_for_each_safe(pos, next, &timerlist->timer_head) { + +diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c +index 3a0fb7e..cd5089a 100644 +--- a/lib/ringbuffer.c ++++ b/lib/ringbuffer.c +@@ -266,7 +266,7 @@ cleanup_hdr: + if (fd_hdr >= 0) { + close(fd_hdr); + } +- if (rb && (flags & QB_RB_FLAG_CREATE)) { ++ if (rb && (rb->shared_hdr != MAP_FAILED) && (flags & QB_RB_FLAG_CREATE)) { + unlink(rb->shared_hdr->hdr_path); + if (rb->notifier.destroy_fn) { + (void)rb->notifier.destroy_fn(rb->notifier.instance); diff --git a/SOURCES/bz1836146-ipc_set_ownership.patch b/SOURCES/bz1836146-ipc_set_ownership.patch new file mode 100644 index 0000000..9d7c43b --- /dev/null +++ b/SOURCES/bz1836146-ipc_set_ownership.patch @@ -0,0 +1,172 @@ +diff -urp libqb-1.0.3.orig/lib/ipc_shm.c libqb-1.0.3/lib/ipc_shm.c +--- libqb-1.0.3.orig/lib/ipc_shm.c 2020-05-20 09:00:31.826899188 +0100 ++++ libqb-1.0.3/lib/ipc_shm.c 2020-05-20 09:11:56.607788472 +0100 +@@ -282,6 +282,8 @@ qb_ipcs_shm_connect(struct qb_ipcs_servi + struct qb_ipc_connection_response *r) + { + int32_t res; ++ char dirname[PATH_MAX]; ++ char *slash; + + qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid); + +@@ -292,6 +294,14 @@ qb_ipcs_shm_connect(struct qb_ipcs_servi + snprintf(r->event, NAME_MAX, "%s-event-%s", + c->description, s->name); + ++ /* Set correct ownership if qb_ipcs_connection_auth_set() has been used */ ++ strlcpy(dirname, c->description, sizeof(dirname)); ++ slash = strrchr(dirname, '/'); ++ if (slash) { ++ *slash = '\0'; ++ (void)chown(dirname, c->auth.uid, c->auth.gid); ++ } ++ + res = qb_ipcs_shm_rb_open(c, &c->request, + r->request); + if (res != 0) { +diff -urp libqb-1.0.3.orig/tests/check_ipc.c libqb-1.0.3/tests/check_ipc.c +--- libqb-1.0.3.orig/tests/check_ipc.c 2017-12-21 09:02:11.000000000 +0000 ++++ libqb-1.0.3/tests/check_ipc.c 2020-05-20 09:07:55.607104804 +0100 +@@ -98,6 +98,8 @@ enum my_msg_ids { + * 7) service availability + * + * 8) multiple services ++ * ++ * 9) setting perms on the sockets + */ + static qb_loop_t *my_loop; + static qb_ipcs_service_t* s1; +@@ -109,6 +111,7 @@ static int32_t num_bulk_events = 10; + static int32_t num_stress_events = 30000; + static int32_t reference_count_test = QB_FALSE; + static int32_t multiple_connections = QB_FALSE; ++static int32_t set_perms_on_socket = QB_FALSE; + + + static int32_t +@@ -360,6 +363,16 @@ s1_connection_destroyed(qb_ipcs_connecti + qb_leave(); + } + ++static int32_t ++s1_connection_accept(qb_ipcs_connection_t *c, uid_t uid, gid_t gid) ++{ ++ if (set_perms_on_socket) { ++ qb_ipcs_connection_auth_set(c, 555, 741, S_IRWXU|S_IRWXG|S_IROTH|S_IWOTH); ++ } ++ return 0; ++} ++ ++ + static void + s1_connection_created(qb_ipcs_connection_t *c) + { +@@ -402,7 +415,7 @@ run_ipc_server(void) + qb_loop_signal_handle handle; + + struct qb_ipcs_service_handlers sh = { +- .connection_accept = NULL, ++ .connection_accept = s1_connection_accept, + .connection_created = s1_connection_created, + .msg_process = s1_msg_process_fn, + .connection_destroyed = s1_connection_destroyed, +@@ -517,7 +530,7 @@ verify_graceful_stop(pid_t pid) + } else { + fail_if(rc == 0); + } +- ++ + return 0; + } + +@@ -1018,7 +1031,7 @@ test_ipc_stress_connections(void) + } + } while (conn == NULL && c < 5); + fail_if(conn == NULL); +- ++ + if (((connections+1) % 1000) == 0) { + qb_log(LOG_INFO, "%d ipc connections made", connections+1); + } +@@ -1448,6 +1461,63 @@ START_TEST(test_ipcc_truncate_when_unlin + END_TEST + #endif + ++// Check perms uses illegal access to libqb internals ++// DO NOT try this at home. ++#include "../lib/ipc_int.h" ++#include "../lib/ringbuffer_int.h" ++START_TEST(test_ipc_server_perms) ++{ ++ pid_t pid; ++ struct stat st; ++ int j; ++ uint32_t max_size; ++ int res; ++ int c = 0; ++ ++ // Can only test this if we are root ++ if (getuid() != 0) { ++ return; ++ } ++ ++ ipc_type = QB_IPC_SHM; ++ set_perms_on_socket = QB_TRUE; ++ max_size = MAX_MSG_SIZE; ++ ++ pid = run_function_in_new_process(run_ipc_server); ++ fail_if(pid == -1); ++ ++ do { ++ conn = qb_ipcc_connect(ipc_name, max_size); ++ if (conn == NULL) { ++ j = waitpid(pid, NULL, WNOHANG); ++ ck_assert_int_eq(j, 0); ++ poll(NULL, 0, 400); ++ c++; ++ } ++ } while (conn == NULL && c < 5); ++ fail_if(conn == NULL); ++ ++ // Check perms - uses illegal access to libqb internals ++ char sockdir[PATH_MAX]; ++ strcpy(sockdir, conn->request.u.shm.rb->shared_hdr->hdr_path); ++ *strrchr(sockdir, '/') = 0; ++ res = stat(sockdir, &st); ++ ++ ck_assert_int_eq(res, 0); ++ ck_assert(st.st_mode & S_IRWXG); ++ ck_assert_int_eq(st.st_uid, 555); ++ ck_assert_int_eq(st.st_gid, 741); ++ ++ res = stat(conn->request.u.shm.rb->shared_hdr->hdr_path, &st); ++ ck_assert_int_eq(res, 0); ++ ck_assert_int_eq(st.st_uid, 555); ++ ck_assert_int_eq(st.st_gid, 741); ++ ++ qb_ipcc_disconnect(conn); ++ verify_graceful_stop(pid); ++} ++END_TEST ++ + static void + test_ipc_service_ref_count(void) + { +@@ -1502,7 +1572,7 @@ END_TEST + #if 0 + static void test_max_dgram_size(void) + { +- /* most implementations will not let you set a dgram buffer ++ /* most implementations will not let you set a dgram buffer + * of 1 million bytes. This test verifies that the we can detect + * the max dgram buffersize regardless, and that the value we detect + * is consistent. */ +@@ -1562,6 +1632,7 @@ make_shm_suite(void) + add_tcase(s, tc, test_ipc_exit_shm, 8); + add_tcase(s, tc, test_ipc_event_on_created_shm, 10); + add_tcase(s, tc, test_ipc_service_ref_count_shm, 10); ++ add_tcase(s, tc, test_ipc_server_perms, 7); + add_tcase(s, tc, test_ipc_stress_connections_shm, 3600); + + #ifdef HAVE_FAILURE_INJECTION diff --git a/SPECS/libqb.spec b/SPECS/libqb.spec new file mode 100644 index 0000000..646aadb --- /dev/null +++ b/SPECS/libqb.spec @@ -0,0 +1,754 @@ +%bcond_with check +%bcond_without testsrpm + +Name: libqb +Version: 1.0.3 +Release: 12%{?dist} +Summary: An IPC library for high performance servers + +Group: System Environment/Libraries +License: LGPLv2+ +URL: https://github.com/ClusterLabs/libqb +Source0: https://github.com/ClusterLabs/libqb/releases/download/v%{version}/%{name}-%{version}.tar.xz + +Patch0: bz1615945-remove-linker-callsites.patch +Patch1: bz1682119-install-tests.patch +Patch2: bz1714854-improve-shm-security.patch +Patch3: bz1718773-avoid-ipc-deadlock.patch +Patch4: bz1836146-ipc_set_ownership.patch +Patch5: bz1836146-covscan-fixes.patch + +BuildRequires: autoconf automake libtool doxygen procps check-devel +# https://fedoraproject.org/wiki/Packaging:C_and_C%2B%2B#BuildRequires_and_Requires +BuildRequires: gcc +# git-style patch application +#BuildRequires: git # for when patches around + +%description +libqb provides high-performance, reusable features for client-server +architecture, such as logging, tracing, inter-process communication (IPC), +and polling. + +%prep +%setup +#autosetup -p1 -S git_am # for when patches around +%patch0 -p1 -b .bz1615945-remove-linker-callsites +%patch1 -p1 -b .bz1682119-install-tests +%patch2 -p1 -b .bz1714854-improve-shm-security.patch +%patch3 -p1 -b .bz1718773-avoid-ipc-deadlock.patch +%patch4 -p1 -b .bz1836146-ipc_set_ownership.patch +%patch5 -p1 -b .bz1836146-covscan-fixes.patch + +%build +./autogen.sh +%configure \ +%if %{with testsrpm} + --enable-install-tests \ +%endif + --disable-static +make %{?_smp_mflags} V=1 + +%if 0%{?with_check} +%check +make VERBOSE=1 check \ + && make -C tests/functional/log_internal VERBOSE=1 check +%endif + +%install +make install DESTDIR=$RPM_BUILD_ROOT +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' +rm -rf $RPM_BUILD_ROOT/%{_docdir}/* + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%license COPYING +%{_sbindir}/qb-blackbox +%{_libdir}/libqb.so.* +%{_mandir}/man8/qb-blackbox.8* + +%package devel +Summary: Development files for %{name} +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: pkgconfig + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + +%files devel +%doc README.markdown +%license COPYING +%{_includedir}/qb/ +%{_libdir}/libqb.so +%{_libdir}/pkgconfig/libqb.pc +%{_mandir}/man3/qb*3* + +%if %{with testsrpm} +%package tests +Summary: Test suite for %{name} +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%files tests +%doc COPYING +%{_libdir}/libqb/tests/* + +%description tests +The %{name}-tests package contains the %{name} test suite. +%endif + + +%changelog +* Wed May 20 2020 Christine Caulfield - 1.0.3-11 + Correctly set socket directory permissions when + qb_ipcs_connection_auth_set() is called + Resolves: rhbz#1836146 + +* Mon Jun 10 2019 Christine Caulfield - 1.0.3-10 + Avoid deadlock in IPC connections + Resolves: rhbz#1718773 + +* Thu Jun 6 2019 Christine Caulfield - 1.0.3-9 + Improve security of SHM files used for IPCs + Resolves: rhbz#1714854 + +* Thu Mar 28 2019 Christine Caulfield - 1.0.3-8 +- Add RHEL-8.1 gating tests + Resolves: rhbz#1682119 + +* Mon Sep 17 2018 Christine Caulfield - 1.0.3-7 +- Remove linker magic in the logging code. + Resolves: rhbz#1615945 + +* Mon Jul 30 2018 Florian Weimer - 1.0.3-6 +- Rebuild with fixed binutils + +* Tue Jun 05 2018 Christine Caulfield - 1.0.3-5 +- Rebuild with newer binutils (hopefully to fix pacemaker/corosync linkage issue) + +* Wed Mar 07 2018 Adam Williamson - 1.0.3-4 +- Rebuild to fix GCC 8 mis-compilation + See https://da.gd/YJVwk ("GCC 8 ABI change on x86_64") + +* Fri Feb 09 2018 Igor Gnatenko - 1.0.3-3 +- Escape macros in %%changelog + +* Wed Feb 07 2018 Fedora Release Engineering - 1.0.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Dec 21 2017 Jan Pokorný - 1.0.3-1 +- Update to libqb-1.0.3, for list of changes see: + https://github.com/ClusterLabs/libqb/releases/tag/v1.0.3 + +* Tue Dec 12 2017 Jan Pokorný - 1.0.2-15 +- Evolution of the previous (rhbz#1478089) + +* Wed Nov 15 2017 Jan Pokorný - 1.0.2-14 +- Evolution of the previous (rhbz#1478089) +- Make -devel package dependency on the main package arch-qualified + +* Tue Oct 31 2017 Jan Pokorný - 1.0.2-13 +- Evolution of the previous (rhbz#1478089) + +* Wed Oct 25 2017 Jan Pokorný - 1.0.2-12 +- Evolution of the previous (rhbz#1478089) + +* Wed Oct 18 2017 Jan Pokorný - 1.0.2-11 +- Evolution of the previous (rhbz#1478089) + +* Fri Oct 13 2017 Jan Pokorný - 1.0.2-10 +- Evolution of the previous (rhbz#1478089) + +* Mon Oct 09 2017 Jan Pokorný - 1.0.2-9 +- Evolution of the previous (rhbz#1478089) + +* Fri Oct 06 2017 Jan Pokorný - 1.0.2-8 +- Evolution of the previous (rhbz#1478089) +- New test included in check phase (as per upsteam) + +* Mon Sep 04 2017 Jan Pokorný - 1.0.2-7 +- Evolution of the previous (rhbz#1478089) + +* Fri Sep 01 2017 Jan Pokorný - 1.0.2-6 +- Better approach so as to mitigate changed treatment of orphaned sections + in ld.bfd/binutils-2.29, resulting in logging facility silently out of order + (rhbz#1478089) +- Related to that, build commands now shown in full to ease the sanity checking +- Adapt spec file per the upstream version (conditionalizing build through + --enable-syslog-tests no longer relevant since v1.0.2) + +* Fri Aug 11 2017 Kalev Lember - 1.0.2-5 +- Bump and rebuild for an rpm signing issue + +* Thu Aug 10 2017 Jan Pokorný - 1.0.2-4 +- Mitigate changed treatment of orphaned sections in ld.bfd/binutils-2.29, + resulting in logging facility silently out of order (rhbz#1478089) + +* Thu Aug 03 2017 Fedora Release Engineering - 1.0.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1.0.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri May 19 2017 Jan Pokorný - 1.0.2-1 +- Update to libqb-1.0.2, for list of changes see: + https://github.com/ClusterLabs/libqb/releases/tag/v1.0.2 + +* Fri Feb 10 2017 Fedora Release Engineering - 1.0.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Nov 25 2016 Jan Pokorný - 1.0.1-1 +- Update to libqb-1.0.1, for list of changes see: + https://github.com/ClusterLabs/libqb/releases/tag/v1.0.1 +- Move qb-blackbox manual page from libqb-devel to libqb + (where the utility itself resides) + +* Mon Apr 4 2016 Jan Pokorný - 1.0-1 +- Update to libqb-1.0, for list of changes see, in order: + https://github.com/ClusterLabs/libqb/releases/tag/v1.0rc1 + https://github.com/ClusterLabs/libqb/releases/tag/v1.0rc2 + https://github.com/ClusterLabs/libqb/releases/tag/v1.0rc3 + https://github.com/ClusterLabs/libqb/releases/tag/v1.0rc4 + https://github.com/ClusterLabs/libqb/releases/tag/v1.0 +- Adapt spec file per the upstream version (drop defattr statements, + autogen.sh call with %%build, conditionalize build process) +- Add gcc as an explicit BuildRequires (required per the new guidelines) +- Do not depend on the rpmbuild-imposed man page archiving method + +* Thu Feb 04 2016 Fedora Release Engineering - 0.17.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Oct 15 2015 Jan Pokorný - 0.17.2-1 +- Update to libqb-0.17.2 + fix check_ipc tests, for list of changes see: + https://github.com/ClusterLabs/libqb/releases/tag/v0.17.2 + +* Wed Jun 17 2015 Fedora Release Engineering - 0.17.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Aug 26 2014 David Vossel - 0.17.1-1 +Fix: ipcs: Correctly allocate receive buffer size +Fix: ipc_socket: Signalhandler must be resetted to Default, use only cleanup_sigpipe to return from qb_ipc_dgram_sock_setup. +Fix: trie: allow modifying the trie map during the notify callback +Fix: fix invalid option when run 'ipcclient -h' +Fix: epoll: don't miss poll events under high load +Fix: ipc_shm: fix error handling in qb_ipcs_shm_connect() +Fix: ringbuffer: fix size in qb_rb_create_from_file() +Fix: ringbuffer: fix qb_rb_open_2() debug format string +Fix: trie: fixes regression caused by ref count refactoring +Fix: ipcc: Properly timeout during recv when timeout value is provided + +* Sun Aug 17 2014 Fedora Release Engineering - 0.17.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 0.17.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + + +* Thu Feb 20 2014 David Vossel - 0.17.0-2 +Fix testsuite timing values + +* Wed Feb 19 2014 David Vossel - 0.17.0-1 +Fix: build: Allow 'make rpm' to work with lightweight tags for release candidates +Fix: spec: reference correct url in spec file +Doc: update broken doxygen link to something that exists +Bump version to 0.17.0 +Low: ipc_socket: further optimize max msg size calculations for fbsd portability tests +Low: ipc_socket: Allow socket max msg size to be calculated more accurately +Fix: fixes travis compile time error +Low: tests: Fixes compile time issue with make check +High: ipcs: Prevent ipc server use after free. +Low: ipc: Remove ipc connection reference given to dispatch functions +High: ipc: Fixes memory leak in server connection accept when client partially connects +IPC: Increase the listen backlog of IPC server +Low: ipcs: Clarifications to the ipcs server callback documentation. +Fix rb.test to avoid overwriting memory during reading. +Low: example: Update client/server example to use server enforced buffer size +Low: Client side buffer retrieval regression test +Feature: New api function to retrieve client buffer size +Low: check_ipc.c: Verify server enforced buffer sizes work +Feature: Enforce buffer size limits on the server side +Low: regession tests for regex log filters +Feature: Filter logs using regex patter on function, format, or filename +ipc_setup: Set SO_PASSCRED on listener socket +Fix: log: Filtering by function and file must match exactly, no substring matches +Low: blackbox: Abort blackbox logging on ringbuffer overwrite reclaim error +High: ipcs: Api function allowing server to retrieve client connection's ipc buffer size +Low: ringbuffer: Abort during chunk reclaim if OVERWRITE flag is set and reclaim fails. +High: blackbox: unique blackbox ringbuffer files per pid +Low: ipc_socket: Fixes fd leak in socket ipc client disconnection +Use sizeof to get the correct size of the sockaddr_un sun_path member in a portable way. Fixes corosync on Mac OS X. +Detect the max signal value that can be used using NSIG macro +Avoid double-decrement of level->todo + +* Thu Aug 1 2013 David Vossel - 0.16.0-1 +Bump version to 0.16.0 ... do not use version 0.15.0 +Update release gpg sign key +Bump the version to 0.15.0 +Merge pull request #83 from davidvossel/master +Low: ipc_socket: Output send event failure as debug instead of error +Low: ipcserver.c: Fix example server's glib mainloop implementation +High: ipc_socket.c: Detect EOF connection on connection STREAM socket +Merge pull request #81 from davidvossel/dgram_max_msg +Low: tests: Add dgram max size detection test +Low: ipc_socket.c: Handle the unlikely event of an EAGAIN or EINTR during dgram max size detection +Merge pull request #82 from davidvossel/master +Fixes detect disconnect on send for tcp example +Fixes sem leak +Fixes less-than-zero comparision of unsigned int +fixes double close +Fixes double close +Fixes double fd close +Fixes fd leak +Prevent use after free in benchmark util +Fixes use ater free in shm disconnect +Fixes use after free during ipcs client disconnect +Remove dead code +Low: check_ipc.c: Verify dgram max size during tests +High: ipcc: Add abilty to verify dgram kernel buffer size meets max msg value +Fixes travis build error +Merge pull request #80 from davidvossel/master +Low: check_ipc.c: fix debug message to only display once. +High: ringbuffer: Make max_size of ringbuffer accurate so shm ipc max msg size value is honored +Low: ipcs: For shm ipc, always retry outstanding notifications when next event is sent +Low: tests: Added test to verify sending ipc msg equal to max size succeeds +Merge pull request #79 from davidvossel/master +Merge pull request #78 from davidvossel/master +Fix: ipcs: Fixes compile time issue reported by travis +Merge pull request #77 from davidvossel/stress_tests_fixes +Low: loop_pool_kqueue: remove potentially noisy dbug statement +Low: tests: rework bulk event msg ipc test +Account for fbsd ENOBUFS during stress test +Low: tests: Adds ipc event stress test to testsuite +Low: ipc_socket: In fbsd send() returns ENOBUFS when dgram queue is full, this should be treated similar to EAGAIN +High: kqueue: Properly enable kqueue filter in poll loop +Low: ipcs: Attempt to resend outstanding event notifications during event send +Merge pull request #75 from davidvossel/ref_count_cleanup +Low: qbipcs.h: update ipcs connection iterator documentation +Merge pull request #74 from davidvossel/ref_count_cleanup +Fix: ipcs: Disconnect shm ipc connection when poll socket returns error on msg receive +Fix: ipcs: Properly disconnect client connection on POLLNVAL or any other error causing connection removal from mainloop. +Simplify internal ipcs ref counting, add comments and document api behavior +Simplifies connection ref counting without changing behavior +Low remove ref-count error in example ipcserver. +Merge pull request #73 from davidvossel/ref_count_cleanup +Merge pull request #72 from davidvossel/master +Low: tests: Verify reading valid blackbox file works +Fix: refcount leak +Fix: ringbuffer: Add file header version field and detect reading corrupted blackbox files using hash value +Fix: tests: On some platforms -ECONNRESET is returned rather than -ENOTCONN after server failure +Fix: tests: Make blackbox_segfault.sh not depend on bash +Hopefully this is the last travis link fix +Fix travis icon (travis is case sensitive) +Fix the github links +Merge pull request #70 from yuusuke/fix_logging +fix a problem when the character string beyond the number of the maximum characters is passed +Merge pull request #68 from r1mikey/upstream +Add a IPC service context pointer and accessors from both the connection and service level. +Enable distcheck on the travis tests +Add atomic_int.h to noinst_HEADERS +Use the new atomic ops in the ringbuffer +Add internal support for the new __atomic gcc builtins +Rename the configure macros from atomic to sync +ringbuffer: use atomic ops on ringbuffer chunk magic +Remove some test code mistakenly committed to the example program. +IPC: make each connection ref the owning service +Indicate when/why qb_rb_force_close() fails to remove share memory files +Typo fixed in configure +Fix "make srpm" +Remove doxygen from travis deps to try and get the job working. +Fix make distcheck +Merge pull request #60 from t-matsuo/fix-makefile-of-tests +add file_change_bytes into check_PROGRAMS and fix a typo +Deal better with corrupt blackbox files. +Merge pull request #58 from inouekazu/fix_connection_state_checking +IPC: fix the connection state checking +LOG: copy the function/filename for dynamic callsites +Deal with /dev/shm issue on Travis builders +Properly discover SO_NOSIGPIPE and MSG_SIGNAL +IPC: fix call to QB_SUN_LEN +list: don't splice empty lists onto the head. +rpl_sem: make destroy more compliant +test: fix unused-but-set-variable warning +test: fix missing-format-attribute warning +RB: make the "sem" abstraction into a notifier +IPC: clean up the connection state checking +Use dgram sockets for message oriented communications +IPC: don't interpret EMSGSIZE and ENOMSG as a disconnect +POLL: prevent a spin if the fd is not removed from the mainloop +add TAGS and ~ files to .gitignore +docs: install qb-blackbox.8 if doxygen is not available. +IPC: seperate ipc_us.c into 2 files +IPC: move utility functions to unix.c +IPC: make sure we return a consistent error when the message is too big. + +* Thu Feb 14 2013 Fedora Release Engineering - 0.14.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Jan 17 2013 Angus Salkeld - 0.14.4-1 +LOG: prevent the last char of the blackbox message from getting lost. +Example: make the blackbox example more practical. +Add the processing which remove notifier at skiplist_destroy function +Add the processing which remove hash node and notifier at hashtable_destroy function +Unify to QB_TRUE/QB_FALSE a boolean value +Document the default prefix in INSTALL +Unify the list processing with qb_list function +Add travis link to the readme. +Fix return code which is an error occurred at pthread function +TEST: add a progam to compare the speed of vsnprintf and qb_vsnprintf_serialize +LOG: add a test for a padded hex int. +Fedora's splint has a strange syntax error, don't fail on it. +LOG: fix truncation in some messages that get padded. +Fix the blackbox formatter when specifing the string len/precision +Fix strlcpy and strlcat functions +IPC: don't over log on disconnect +Make sure we don't use the format string whilst it is getting changed. +ptrie: deref the current node in trie_iter_free() +LOG: fix the format comparison to avoid generating multiple entries. +LOG: set the return code when calloc fails +IPC: call poll if we are mid message and get EAGAIN +Remove extra ";" +IPC: set the error more correctly when qb_sys_mmap_file_open() fails. +Make sure that mmap'ed files smaller than a page size are written to. +example/test: check for error in qb_ipc_run() +example: check for error in qb_ipc_run() +TEST: fix typo s/,/; in check_ipc.c + +* Mon Oct 29 2012 Angus Salkeld - 0.14.3-2 +Fix test code highlighted by new check version +Remove the call to autogen.sh - not needed anymore. + +* Mon Oct 29 2012 Angus Salkeld - 0.14.3-1 +IPC: Pass the timeout to poll() if the recv function returns EAGAIN +LOG: make the format comparison safe and sane +LOG: don't break on empty callsites, just ignore them +LOG: use the array callback to register new callsites +array: add a mechanism to get a callback when a bin is allocated +Solaris based operating systems don't define MSG_NOSIGNAL and SO_NOSIGPIPE. +Make sure atomic's are initialized (for non-gcc atomic). + +* Wed Sep 12 2012 Angus Salkeld - 0.14.2-2 +Fix a crash in ptrie if you iterate over the map in the deleted notifier. + +* Mon Sep 10 2012 Angus Salkeld - 0.14.2-1 +Get libqb building on cygwin. +ipc_us: slightly more robust cmsg handling +ipc_us: on Linux, set SO_PASSCRED on the sending socket too +ipc_us: clear request unused fields +TEST: Include writing and reading the blackbox in the log_long_msg test +LOG: fix qb_vsnprintf_deserialize() +blackbox: fix 64-bit big-endian issues +Remove IPC_NEEDS_RESPONSE_ACK and turn off shm ipc on solaris +Define unix path max for openbsd +Only turn on ipc_needs_response_ack=yes for solaris +Some improvements to kqueue usage. +kqueue: drop log message to trace. +Fix splint warning +openbsd requires netinet/in.h before arpa/inet.h +Avoid strcpy() use strlcpy() instead. +Fix kqueue complile warnings +openbsd doesn't have EBADMSG +openbsd has a different UNIX_PATH_MAX +LOG: change qb_vsprintf_serialize() into qb_vsnprintf_serialize() +TEST: increase timeout to 6 secs as the recv timeout is 5 secs +TEST: get the logic right - grrr. +Turn off attribute_section on netbsd +Some missing pshared semaphore checks +Cleanup the checks for pshared semaphores +Add a config check for pthread_mutexattr_setpshared +Remove uses of timersub and use qb_util_stopwatch +RB: change the #error to ENOTSUP if no usable shared process sem +LOOP-KQUEUE: fix reference before assignment. +build: fix libqb.pc creation and make maintainer-clean +LOG: Make sure the semaphores are initialized. +build: remove bashism in cc support check +Catch disconnected sockets on Solaris +Don't free rb->shared_hdr in qb_rb_create_from_file() +Check error return of qb_ipcs_uc_recv_and_auth() +Fix removal of automatically installed doc files when building rpms +Add the mailing list to the travis email notifications. +Work around debian not setting the arch path in splint. +Remove color-tests and parallel-tests automake options. +Add travis continuous integration config +LOG: Invoke custom log filter function if tag changes +tests/rbwriter: don't ignore write failure +ipcs: avoid use-after-free for size-0 || disconnect-request + +* Wed Jul 18 2012 Angus Salkeld - 0.14.1-1 +RB: set the new read pointer after clearing the header (#839605). +RB: improve the debug print outs +RB: be more explicit about the word alignment +RB: cleanup the macros for wrapping the index +RB: use sem_getvalue as a tie breaker when read_pt == write_pt +RB: if read or peek don't get the message then re-post to the semaphore +RB: convert the rb_peek() status into a recv like status. +RB: use internal reclaim function +IPC: use calloc instead of malloc to fix valgrind warnings +Upgrade the doxygen config. +Fix a valgrind error. + +* Sun Jun 24 2012 Angus Salkeld - 0.14.0-1 +LOG: fix threaded logging. +Add user control of the permissions that are set on the shared mem files +LOG: Restrict string trucation during serialization to when a precision is specified +LOG: Gracefully fail when the caller exceeds QB_LOG_MAX_LEN +LOG: Observe field widths when serializing string arguments +RB: use the same mechanism in reclaim as read/peek to detect end-of-ring +Add needs_response_ack option to ./check +RB: fix wrong sem_flg IPC_NOWAIT option +TESTS: fix warning about unused functions +Remove D_FORTIFY_SOURCE from check. +Open shared mem file in /dev/shm only for linux +Don't use msg_flags on solaris (recvmsg). +Turn off attribute_section on solaris +ipc example: add -e (events) option +IPC: if the server returns EAGAIN or ETIMEOUT the check the connection +LOG: make it possible to fsync() on each file log. +IPC: make sure that the created callback happens before dispatches +LOG: fix the printing of %%p in the blackbox +IPC: On bsd's use the notifier for responses +IPC: interpret ECONNRESET and EPIPE as ENOTCONN +cleanup some warnings +config: use newer AC_COMPILE_IFELSE() +blackbox: fix %%p formatting +LOG: put all fields in the blackbox (added priority and tags) +example: make the priority uint8_t +Remove strerror out of check_funcs +RB: fix compiler warning. +Add replacement function stpcpy +Add missing AC_TYPE_UINT16_T to configure.ac +Use AC_FUNC_STRERROR_R and STRERROR_R_CHAR_P +Add stpcpy strcasecmp to the check_funcs +Move some conditional defines into code (from the configure script) +Remove some unused configure checks +Remove message queues +Check for union semun properly +Blackbox: provide more space for log messages when reading from the blackbox. +Add the blackbox reader manpage to the spec file +Enable error logging for the blackbox reader +RB: Read the file size into an initialized variable of the correct size +Add a tool to dump the blackbox. +RB: to be safer save the read and write pointers at the top of the blackbox +avoid unwarranted use of strncpy: use memcpy instead +blackbox: fix the print_from_file() +RB: add an option to not use any semaphores +LOG: tweak the blackbox format string +LOG: accept NULL strings into the blackbox +LOG: protect close and reload from calling log +Add benchmark option (-b) to examples/ipcclient +TEST: make rbreader/writer more like the other benchmarking apps +IPC: log the connection description in all logs +TEST: re-organise the ipc test suites +IPC: only modify the dispatch if we get EAGAIN +Correctly display timestamp in blackbox + +* Thu May 10 2012 Angus Salkeld - 0.13.0-1 +- Remove unneccessary __attribute__ ((aligned(8))) from internal headers +- IPC: add a new function to get (and alloc) the extended stats. +- Revert "Add the event queue length to the connection stats." +- IPC: cleanup better on a failed client connect. +- IPC(soc): be more consistent with control struct size +- IPC: kill a compiler warning +- IPC(soc): pass in the correct size into munmap() +- TEST: Use /bin/sh not /bin/bash +- TEST: check for lost shared mem on bsd too +- rb: cleanup the semaphores +- Fix some small issues in ./check +- Cleanup the .gitignore files +- configure.ac tweaks +- Remove HZ and use sysconf instead. +- SUN_LEN() macro is present if __EXTENSIONS__ is defined on Illumos +- PF_UNIX is a POSIX standard name +- Test for log facility names +- IPC: drop log message to debug. +- IPC: fix retrying of partial recv's and sends. +- IPC: initialize enough shared mem for all 3 one way connections. +- IPC: keep retrying to recv the socket message if partially recv'ed (part 2) +- IPC: keep retrying to recv the socket message if partially recv'ed +- IPC: handle the server shutdown better +- IPC: handle a connection disconnect from the server better +- IPC: make it possible to send events in the connected callback. +- Add the event queue length to the connection stats. +- IPC: add a is_connected client side function. +- Fix typo in ./check +- docs: clarify the need to use request/response headers +- Remove unused local variable +- IPC: change the socket recv function to read the response header. +- Add some special commands into the ipc example +- TEST: improve the tracing in the ipc tests. +- Make "make (s)rpm" work more reliably +- TEST: add a test to confirm we get the events we send. +- TEST: reuse send_and_check for events. +- IPC: make it possible for a root client to talk to a non-root server. +- Run ./Lindent in the examples directory +- Add some debug code to the ipcclient example +- IPC: make sure ipc (socket) clients can connect to a server running as root. +- IPC: allow qb to bump the max_message_size +- IPC: check for a sane minimum max_message_size +- add rpl_sem.h loop_poll_int.h to noinst_headers +- Handle errors more consistently +- call recv_ready on socket types +- Handle a recv of size 0 +- make bsd shm path better by default. +- Fix kqueue on freebsd. +- Get the example socket includes right. +- Fix kqueue compiling. +- POLL: seperate out the poll/epoll and add kqueue +- Test existence of getpeer* functions +- Add inet header to tcpclient example +- Don't link with setpshared if unavailable +- NetBSD doesn't have semun defined +- Use MADV_NOSYNC only on systems where available +- Use SCHED_BATCH only on platforms where available +- Fix a bug introduced by the bsd patch. +- Cleanup the selection of semaphores to use +- Fix some leaks in the logging. +- Try and improve the portability on bsd variants. + +* Sun Mar 11 2012 Angus Salkeld - 0.11.1-1 +- configue libqb to not use epoll as it seems broken (#800865) +- LOOP: remove some old timerfd code. +- TEST: add a test to check the order of the jobs +- LOOP: when new jobs are added they are added to the head instead of the tail. +- LOG: Now the array is self locking we can make the lookup array dynamic +- Add locking to the array when growing. +- IPC: make the _request_q_len_get() function more obvious. +- IPC: fix multiple receives from qb_ipc_us_recv() +- IPC: make sure that the wrong union member is not written to. +- TIMER: check for null timer handle + +Wed Mar 7 2012 Angus Salkeld - 0.11.0-1 +- ARRAY: cleanup the pointer sizeof() +- LOG: turn off __attribute__(section) for powerpc (not working) +- TESTS: move the util tests into "slow-tests" (i.e. optional) +- TEST: make the test_priority the same type as in the callsite +- LOG: make the log arrays manually grow-able since we need to lock the calls. +- RB: fix test failure on ppc +- RB: change the name of the size to word_size to be more clear +- TEST: add some more signal tests. +- LOOP: fix deletion of signal handlers when they are pending +- LOOP: signal handlers were always added as high priority. +- TEST: deal with mac's limited sed +- check: add debugging to the configure options and remove unused options +- TEST: properly clear the filters +- LOG: expose the mechanism to get a dynamic callsite. +- Revert part of my COARSE grained timer commit +- Remove timerfd usage and go back to timelist. +- UTIL: if possible use COARSE resolution clocks - they are much faster. +- ARRAY: save memory (in the bins array) and allow holes in the array +- LOOP: add qb_loop_timer_is_running() +- LOOP: allow stop() and run() to be called with NULL loop instance. +- LOOP: fix doxygen parameter comment +- LOG: add stdout target +- LOOP: add a function to delete jobs +- LOG: remove debug printf's +- LOG: remove an old/incorrect doxygen comment. +- LOG: add a hostname %%H format specifier. +- LOG: Add qb_log_filter_fn_set() + +* Tue Feb 14 2012 Angus Salkeld - 0.10.1-1 +- Fix "make distcheck" add include path to AM_CPPFLAGS +- Bump the version to 0.10.1 +- clang: Remove unused code +- TEST: make the ipc failure test closer to corosync's case. +- RB: add a debug message if trying to read a message of the wrong size +- IPC: split up the recv into chuncks of 2 seconds. (#788742) +- Be more consistent with the internal logs. +- LOOP: make it possible to pass in NULL as the default loop instance +- RB: use the proper struct not the typedef in the implementation. +- RB: Fix potential mem leak +- Don't mix enums (QB_TRUE/TRUE) +- use random() not rand() +- Remove dead code +- set umask before calling mkstemp() +- Use safer versions of string functions (strcpy -> strlcpy) +- Increase the coverity aggressiveness +- TEST: make the loop ratelimit test more forgiving. + +* Tue Feb 07 2012 Angus Salkeld - 0.10.0-1 +- LOOP: handle errors from the poll function +- LOOP: make the item type applicable to jobs too. +- LOOP: fix the todo calculations. +- TEST: check for a single job causing a cpu spin +- LOOP: prevent jobs from consuming too much cpu. +- Get coverity to ignore this warning. +- Change example code to use fgets instead of gets +- LOG: pass the result of qb_log_thread_start() back to the user +- Fix some issues found by clang +- Add clang-analyzer check +- Add a split timer to the stopwatch. +- IPC: merge common code into new function +- IPC: better handle a disconnect been called from within connection_created() +- IPC: fix scary typo +- IPC: fix server error handling + +* Mon Feb 06 2012 Angus Salkeld - 0.9.0-2 +- Fix a spin in the mainloop when a timer or poll gets removed + When in the job queue (#787196). + +* Fri Jan 27 2012 Angus Salkeld - 0.9.0-1 +- Rebased to 0.9.0 + +* Tue Jan 10 2012 Angus Salkeld - 0.8.1-2 +- fix qb_timespec_add_ms() + +* Thu Jan 5 2012 Angus Salkeld - 0.8.1-1 +- Rebased to 0.8.1 (#771914) + +* Thu Nov 17 2011 Angus Salkeld - 0.7.0-1 +- Rebased to 0.7.0 (#754610) + +* Thu Sep 1 2011 Angus Salkeld - 0.6.0-2 +- LOG: fix the default syslog filter + +* Tue Aug 30 2011 Angus Salkeld - 0.6.0-1 +- Rebased to 0.6.0 which includes (#734457): +- Add a stop watch +- LOG: serialize the va_list, don't snprintf +- LOG: change active list into array access +- atomic: fix qb_atomic_pointer macros +- LOG: allow the thread priority to be set. +- Fix splint warning on ubuntu 11.04 + +* Mon Jul 18 2011 Angus Salkeld - 0.5.1-1 +- Rebased to 0.5.1 which includes: +- LOOP: make the return more consistent in qb_loop_timer_expire_time_get() +- LOG: add string.h to qblog.h +- Add a qb_strerror_r wrapper. +- don't let an invalid time stamp provoke a NULL dereference +- LOG: move priority check up to prevent unnecessary format. +- rename README to README.markdown + +* Wed Jun 8 2011 Angus Salkeld - 0.5.0-1 +- Rebased to 0.5.0 which includes: +- new logging API +- support for sparc +- coverity fixes + +* Tue Feb 8 2011 Angus Salkeld - 0.4.1-2 +- SPEC: improve devel files section +- SPEC: remove global variables + +* Mon Jan 31 2011 Angus Salkeld - 0.4.1-1 +- SPEC: add procps to BuildRequire +- SPEC: remove automake and autoconf from BuildRequire +- SPEC: remove call to ./autogen.sh +- SPEC: update to new upstream version 0.4.1 +- LOOP: check read() return value +- DOCS: add missing @param on new timeout argument +- BUILD: only set -g and -O options if explicitly requested. +- BUILD: Remove unneccessary check for library "dl" +- BUILD: improve the release build system + +* Fri Jan 14 2011 Angus Salkeld - 0.4.0-2 +- remove "." from Summary +- Add "check-devel to BuildRequires +- Add "make check" to check section +- Changed a buildroot to RPM_BUILD_ROOT +- Document alphatag, numcomm and dirty variables. + +* Sun Jan 09 2011 Angus Salkeld - 0.4.0-1 +- Initial release