Skip to content

Commit

Permalink
libmultipath: avoid -Warray-bounds error in uatomic_xchg()
Browse files Browse the repository at this point in the history
The use of uatomic_xchg() in alias.c causes a -Warray-bounds error
on distributions using gcc 12, such as Fedora 37. This is a similar
error to 2534c4f ("libmultipath: avoid -Warray-bounds error with gcc
12 and musl libc"). This happens only with liburcu 0.13 and earlier,
and only with certain gcc versions. See liburcu commit 835b9ab
("Fix: x86 and s390 uatomic: __hp() macro warning with gcc 11").

Enhance the fix for 2534c4f by a workaround for uatomic_xchg(), and
introduce the macro URCU_VERSION (originally only used for multipathd)
globally.

Signed-off-by: Martin Wilck <[email protected]>
  • Loading branch information
mwilck committed Sep 12, 2023
1 parent 1f1f159 commit 517514c
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4
WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \
-Werror=implicit-function-declaration -Werror=format-security \
$(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS)
CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \
CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \
-DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \
-DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \
-DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \
Expand Down
5 changes: 5 additions & 0 deletions create-config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ TEST_URCU_TYPE_LIMITS = $(shell \
$(CC) -c -Werror=type-limits -o /dev/null -xc - 2>/dev/null \
|| echo -Wno-type-limits )

URCU_VERSION = $(shell \
$(PKG_CONFIG) --modversion liburcu 2>/dev/null | \
awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }')

DEFINES :=

ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0)
Expand Down Expand Up @@ -168,6 +172,7 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h
@echo creating $@
@echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@
@echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@
@echo "D_URCU_VERSION := $(call URCU_VERSION)" >>$@
@echo "SYSTEMD := $(SYSTEMD)" >>$@
@echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@
@echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@
Expand Down
5 changes: 3 additions & 2 deletions libmultipath/alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "devmapper.h"
#include "strbuf.h"
#include "time-util.h"
#include "lock.h"

/*
* significant parts of this file were taken from iscsi-bindings.c of the
Expand Down Expand Up @@ -299,7 +300,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event)
pthread_mutex_unlock(&timestamp_mutex);

if (changed) {
uatomic_xchg(&bindings_file_changed, 1);
uatomic_xchg_int(&bindings_file_changed, 1);
condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld",
__func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000);
} else
Expand Down Expand Up @@ -773,7 +774,7 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings,
int rc = 0, ret, fd;
FILE *file;
struct stat st;
int has_changed = uatomic_xchg(&bindings_file_changed, 0);
int has_changed = uatomic_xchg_int(&bindings_file_changed, 0);

if (!force) {
if (!has_changed) {
Expand Down
21 changes: 13 additions & 8 deletions libmultipath/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@ struct mutex_lock {
int waiters; /* uatomic access only */
};

#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12
static inline void init_lock(struct mutex_lock *a)
{
pthread_mutex_init(&a->mutex, NULL);
uatomic_set(&a->waiters, 0);
}

#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif

static inline void init_lock(struct mutex_lock *a)
static inline int uatomic_xchg_int(int *ptr, int val)
{
pthread_mutex_init(&a->mutex, NULL);
uatomic_set(&a->waiters, 0);
return uatomic_xchg(ptr, val);
}

static inline void lock(struct mutex_lock *a)
Expand All @@ -31,6 +36,10 @@ static inline void lock(struct mutex_lock *a)
uatomic_dec(&a->waiters);
}

#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00
#pragma GCC diagnostic pop
#endif

static inline int trylock(struct mutex_lock *a)
{
return pthread_mutex_trylock(&a->mutex);
Expand All @@ -51,10 +60,6 @@ static inline bool lock_has_waiters(struct mutex_lock *a)
return (uatomic_read(&a->waiters) > 0);
}

#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12
#pragma GCC diagnostic pop
#endif

#define lock_cleanup_pop(a) pthread_cleanup_pop(1)

void cleanup_lock (void * data);
Expand Down
2 changes: 0 additions & 2 deletions multipathd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ CLI := multipathc
MANPAGES := multipathd.8

CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \
$(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \
awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \
-DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS)

#
Expand Down

0 comments on commit 517514c

Please sign in to comment.