Compare commits

...

No commits in common. 'c9' and 'i8c' have entirely different histories.
c9 ... i8c

2
.gitignore vendored

@ -1 +1 @@
SOURCES/libqb-2.0.6.tar.xz
SOURCES/libqb-1.0.3.tar.xz

@ -1 +1 @@
a2983bcaf2d5d7faf780db9c964a149eeb5715c0 SOURCES/libqb-2.0.6.tar.xz
5e45fd90b9468747577460bc7c28d9e4cf709b9d SOURCES/libqb-1.0.3.tar.xz

@ -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 <assert.h>
- 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 <assert.h>
- 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 <assert.h>
- 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 <qb/qbutil.h>
#include <qb/qbconfig.h>
-#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 <assert.h> /* possibly needed for QB_LOG_INIT_DATA */
-#include <dlfcn.h> /* 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.<digit>" 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 <regex.h>
-#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.<digit>/$${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)

@ -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 <nobody@nowhere.org> - @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

@ -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;

@ -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);
}

@ -0,0 +1,32 @@
commit bfa90160e5856cd91e7c3e58bfd50387a41b8ca9
Author: Christine Caulfield <ccaulfie@redhat.com>
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);

@ -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

@ -0,0 +1,25 @@
diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c
index 23eeabb..0a720c8 100644
--- a/lib/ipc_setup.c
+++ b/lib/ipc_setup.c
@@ -447,6 +447,7 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
int32_t res;
struct qb_ipc_connection_request request;
struct ipc_auth_data *data;
+ int retry_count = 0;
#ifdef QB_LINUX
int off = 0;
int on = 1;
@@ -478,7 +479,12 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
}
qb_ipc_us_ready(&c->setup, NULL, -1, POLLIN);
+retry:
res = qb_ipc_us_recv_msghdr(data);
+ if (res == -EAGAIN && ++retry_count < 10) {
+ usleep(100000);
+ goto retry;
+ }
#ifdef QB_LINUX
setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &off,

@ -1,46 +0,0 @@
commit 5594d377ac73d37c06bbad1798e87a65f9a12e07
Author: Chrissie Caulfield <ccaulfie@redhat.com>
Date: Fri Nov 25 07:38:20 2022 +0000
ipc: Retry receiving credentials if the the message is short (#476)
ipc: Retry receiving credentials if the the message is short
rhbz#2111711 refers
diff --git a/lib/ipc_setup.c b/lib/ipc_setup.c
index 0ef9bb6..0de7115 100644
--- a/lib/ipc_setup.c
+++ b/lib/ipc_setup.c
@@ -473,11 +473,15 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
return 0;
}
+#define AUTH_RECV_MAX_RETRIES 10
+#define AUTH_RECV_SLEEP_TIME_US 100
+
/* Called from ipcc_connect_continue() when async connect socket is active */
int qb_ipcc_setup_connect_continue(struct qb_ipcc_connection *c, struct qb_ipc_connection_response *r)
{
struct ipc_auth_data *data;
int32_t res;
+ int retry_count = 0;
#ifdef QB_LINUX
int off = 0;
#endif
@@ -486,8 +490,14 @@ int qb_ipcc_setup_connect_continue(struct qb_ipcc_connection *c, struct qb_ipc_c
qb_ipcc_us_sock_close(c->setup.u.us.sock);
return -ENOMEM;
}
-
+retry:
res = qb_ipc_us_recv_msghdr(data);
+ if (res == -EAGAIN && ++retry_count < AUTH_RECV_MAX_RETRIES) {
+ struct timespec ts = {0, AUTH_RECV_SLEEP_TIME_US*QB_TIME_NS_IN_USEC};
+ struct timespec ts_left = {0, 0};
+ nanosleep(&ts, &ts_left);
+ goto retry;
+ }
#ifdef QB_LINUX
setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &off,

@ -1,51 +0,0 @@
commit 1bbaa929b77113532785c408dd1b41cd0521ffc8
Author: Chrissie Caulfield <ccaulfie@redhat.com>
Date: Thu Jul 20 07:19:01 2023 +0100
log: fix potential overflow with long log messages (#490)
qb_vsnprintf_serialize was called with 'max_size' as the
limiting number for the length of the formatted log
message. But the buffer also needs to contain the
log header (given by 'actual_size'), so we now pass
't->max_line_length' as the maximum length of the
formatted log message to limit space to the actual
bytes left
Also added error checks to the blackbox calls at
the end of the test, as these now provide a proper
test that the BB is functioning. Before they were
masking failures.
diff --git a/lib/log_blackbox.c b/lib/log_blackbox.c
index 3e30504..8519a48 100644
--- a/lib/log_blackbox.c
+++ b/lib/log_blackbox.c
@@ -110,8 +110,8 @@ _blackbox_vlogger(int32_t target,
chunk += sizeof(uint32_t);
/* log message */
- msg_len = qb_vsnprintf_serialize(chunk, max_size, cs->format, ap);
- if (msg_len >= max_size) {
+ msg_len = qb_vsnprintf_serialize(chunk, t->max_line_length, cs->format, ap);
+ if (msg_len >= t->max_line_length) {
chunk = msg_len_pt + sizeof(uint32_t); /* Reset */
/* Leave this at QB_LOG_MAX_LEN so as not to overflow the blackbox */
diff --git a/tests/check_log.c b/tests/check_log.c
index 039a4bb..e5abf40 100644
--- a/tests/check_log.c
+++ b/tests/check_log.c
@@ -832,8 +832,10 @@ START_TEST(test_log_long_msg)
qb_log(LOG_INFO, "Message %d %d - %s", lpc, lpc%600, buffer);
}
- qb_log_blackbox_write_to_file("blackbox.dump");
- qb_log_blackbox_print_from_file("blackbox.dump");
+ rc = qb_log_blackbox_write_to_file("blackbox.dump");
+ ck_assert_int_gt(rc, 0);
+ rc = qb_log_blackbox_print_from_file("blackbox.dump");
+ ck_assert_int_le(rc, 0);
unlink("blackbox.dump");
qb_log_fini();
}

@ -1,59 +1,69 @@
%bcond_without check
%bcond_with check
%bcond_without testsrpm
Name: libqb
Version: 2.0.6
Release: 4%{?dist}
Summary: Library providing high performance logging, tracing, ipc, and poll
Version: 1.0.3
Release: 13%{?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: bz2149647-connretry-recv.patch
Patch1: bz2236171-fix-bb-overflow.patch
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
Patch6: bz2111711-connretry-recv.patch
BuildRequires: autoconf automake libtool
BuildRequires: check-devel
BuildRequires: doxygen
BuildRequires: autoconf automake libtool doxygen procps check-devel
# https://fedoraproject.org/wiki/Packaging:C_and_C%2B%2B#BuildRequires_and_Requires
BuildRequires: gcc
BuildRequires: procps
# for ipc.test only (part of check scriptlet)
BuildRequires: pkgconfig(glib-2.0)
# git-style patch application
BuildRequires: git-core
# For doxygen2man
BuildRequires: libxml2-devel
BuildRequires: make
#BuildRequires: git # for when patches around
%description
A "Quite Boring" library that provides high-performance, reusable features for client-server
libqb provides high-performance, reusable features for client-server
architecture, such as logging, tracing, inter-process communication (IPC),
and polling.
%prep
%autosetup -p1
%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
%patch6 -p1 -b .bz2111711-connretry-recv.patch
%build
./autogen.sh
%configure \
%if %{with testsrpm}
--enable-install-tests \
%endif
%endif
--disable-static
%{make_build}
make %{?_smp_mflags} V=1
%if 0%{?with_check}
%check
make check V=1
make VERBOSE=1 check \
&& make -C tests/functional/log_internal VERBOSE=1 check
%endif
%install
%{make_install}
find $RPM_BUILD_ROOT -name '*.la' -delete
make install DESTDIR=$RPM_BUILD_ROOT
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
rm -rf $RPM_BUILD_ROOT/%{_docdir}/*
%ldconfig_scriptlets
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%license COPYING
@ -63,6 +73,7 @@ rm -rf $RPM_BUILD_ROOT/%{_docdir}/*
%package devel
Summary: Development files for %{name}
Group: Development/Libraries
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig
@ -72,6 +83,7 @@ developing applications that use %{name}.
%files devel
%doc README.markdown
%license COPYING
%{_includedir}/qb/
%{_libdir}/libqb.so
%{_libdir}/pkgconfig/libqb.pc
@ -92,116 +104,40 @@ The %{name}-tests package contains the %{name} test suite.
%endif
%package -n doxygen2man
Summary: Program to create nicely-formatted man pages from Doxygen XML files
Requires: %{name}%{?_isa} = %{version}-%{release}
%description -n doxygen2man
This package contains a program to create nicely-formatted man pages from Doxygen XML files
%files -n doxygen2man
%{_bindir}/doxygen2man
%{_mandir}/man1/doxygen2man.1.gz
%changelog
* Fri Sep 8 2023 Christine Caulfield <ccaulfie@redhat.com> 2.0.6-4
- bump rpm version for rhel-exception build
Resolves: rhbz#2230712
* Fri Sep 1 2023 Christine Caulfield <ccaulfie@redhat.com> 2.0.6-3
- blackbox: fix buffer overflow with long log lines
Resolves: rhbz#2236171
* Thu Dec 1 2022 Christine Caulfield <ccaulfie@redhat.com> 2.0.6-1
- ipc: Retry receiving credentials if the the message is short
Resolves: rhbz2149647
* Wed Apr 20 2022 Christine Caulfield <ccaulfie@redhat.com> 2.0.6-1
- Rebase to 2.0.6
Resolves: rhbz#2072903
* Thu Mar 3 2022 Christine Caulfield <ccaulfie@redhat.com> 2.0.3-8
- Fix negative errno in qb_ipcc_connect (introduced in 2.0.3-4)
Resolves: rhbz#2057527
* Wed Jan 19 2022 Christine Caulfield <ccaulfie@redhat.com> 2.0.3-7
- Bump soname for async-connect API addition
Resolves: rhbz#bz2031865
* Mon Jan 10 2022 Christine Caulfield <ccaulfie@redhat.com> 2.0.3-6
- Fix gating.yaml for RHEL-9
Resolves: rhbz#bz2031865
* Mon Jan 10 2022 Christine Caulfield <ccaulfie@redhat.com> 2.0.3-5
- Add gating.yaml from RHEL
Resolves: rhbz#bz2031865
* Fri Jan 7 2022 Christine Caulfield <ccaulfie@redhat.com> 2.0.3-4
- Add async connect call for Pacemaker
Resolves: rhbz#bz2031865
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 2.0.3-3
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 2.0.3-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Wed Mar 3 2021 Christine Caulfield <ccaulfie@redhat.com> 2.0.3
- Rebase to version 2.0.3
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.0.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Wed Jul 29 2020 Christine Caulfield <ccaulfie@redhat.com> 2.0.2
- Rebase to version 2.0.2
* Wed Jul 29 2020 Christine Caulfield <ccaulfie@redhat.com> 2.0.1-2
- Replace deprecated check macros fail_if() and fail_unless() with ck_assert()
see check BZ: bz1850198
* Wed Jul 29 2020 Christine Caulfield <ccaulfie@redhat.com> 2.0.1-1
- Rebase to version 2.0.1
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.0.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Wed May 13 2020 Christine Caulfield <ccaulfie@redhat.com> 2.0.0-1
- Rebase to version 2.0.0
* Wed Jul 26 2023 MSVSphere Packaging Team <packager@msvsphere.ru> - 1.0.3-13
- Rebuilt for MSVSphere 8.8
* Thu Apr 23 2020 Christine Caulfield <ccaulfie@redhat.com> 1.0.5-6
- Further fix for qblist when compiling on gcc10
Affects users of the package rather than libqb itself
* Mon Dec 12 2022 Christine Caulfield <ccaulfie@redhat.com> - 1.0.3-13
ipc: Retry receiving credentials if the the message is short
Resolves: rhbz#2151300
* Mon Apr 6 2020 Peter Robinson <pbrobinson@fedoraproject.org> 1.0.5-5
- Upstream fix for test failures (fix FTBFS)
- spec cleanups
* Wed May 20 2020 Christine Caulfield <ccaulfie@redhat.com> - 1.0.3-11
Correctly set socket directory permissions when
qb_ipcs_connection_auth_set() is called
Resolves: rhbz#1836146
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.0.5-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Jun 10 2019 Christine Caulfield <ccaulfie@redhat.com> - 1.0.3-10
Avoid deadlock in IPC connections
Resolves: rhbz#1718773
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.0.5-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Thu Jun 6 2019 Christine Caulfield <ccaulfie@redhat.com> - 1.0.3-9
Improve security of SHM files used for IPCs
Resolves: rhbz#1714854
* Wed Jun 12 2019 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.5-2
- Fix temporary channel priority loss, up to deadlock-worth
(upstream patchset https://github.com/ClusterLabs/libqb/pull/354)
* Thu Mar 28 2019 Christine Caulfield <ccaulfie@redhat.com> - 1.0.3-8
- Add RHEL-8.1 gating tests
Resolves: rhbz#1682119
* Fri Apr 26 2019 Jan Pokorný <jpokorny+rpm-libqb@redhat.com> - 1.0.5-1
- Update to libqb-1.0.5, for list of changes see:
https://github.com/ClusterLabs/libqb/releases/tag/v1.0.4
https://github.com/ClusterLabs/libqb/releases/tag/v1.0.5
(note that 1.0.4 is botched from pacemaker/corosync cluster stack
perspective so that is intentionally skipped)
- Includes an important fix for a security issue (CVE-2019-12779,
https://github.com/ClusterLabs/libqb/issues/338)
* Mon Sep 17 2018 Christine Caulfield <ccaulfie@redhat.com> - 1.0.3-7
- Remove linker magic in the logging code.
Resolves: rhbz#1615945
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.0.3-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Mon Jul 30 2018 Florian Weimer <fweimer@redhat.com> - 1.0.3-6
- Rebuild with fixed binutils
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.0.3-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jun 05 2018 Christine Caulfield <ccaulfie@redhat.com> - 1.0.3-5
- Rebuild with newer binutils (hopefully to fix pacemaker/corosync linkage issue)
* Wed Mar 07 2018 Adam Williamson <awilliam@redhat.com> - 1.0.3-4
- Rebuild to fix GCC 8 mis-compilation

Loading…
Cancel
Save