On Sun, 25 Feb 2024 at 07:45, Steve Langasek <vorlon@xxxxxxxxxx> wrote: > > Hi, > > Adding James and Christian directly to the email, as frequent contributors > to libselinux, for visibility. > > Debian and Ubuntu are going to have to do something with libselinux within > the week, and I'd greatly prefer that the "something" not be breaking ABI > compatibility with upstream. > > Thanks, > -- > Steve Langasek Give me a lever long enough and a Free OS > Debian Developer to set it on, and I can move the world. > Ubuntu Developer https://www.debian.org/ > slangasek@xxxxxxxxxx vorlon@xxxxxxxxxx > > On Sat, Feb 17, 2024 at 07:08:14PM -0800, Steve Langasek wrote: > > From b23c9044b542b8807f57f4691f4bd1149cbee04c Mon Sep 17 00:00:00 2001 > > From: Steve Langasek <steve.langasek@xxxxxxxxxxxxx> > > Date: Thu, 15 Feb 2024 15:22:45 -0800 > > Subject: [PATCH] Always build for LFS mode on 32-bit archs. > > > > Maintains the type signature of the existing matchpathcon_filespec_add() > > entry point on 32-bit archs but maps the API to a new > > matchpathcon_filespec_add64() entry point that takes a 64-bit ino_t argument > > instead. > > > > Software on 32-bit Linux ports which historically use a 32-bit time_t (thus > > affected by the y2038 problem) have, as a precondition of migrating to > > 64-bit time_t, that they also migrate to large filesystem support because > > glibc does not provide entry points for the cross-product of > > (LFS: yes, LFS: no) x (time_t: 32, time_t: 64). > > > > In order to support smooth migration of such operating systems from 32-bit > > time_t to 64-bit time_t, it is useful for libselinux to: > > > > - provide entry points on 32-bit systems for both LFS and non-LFS variants > > of the API (as glibc itself does) > > - use LFS internally for all filesystem calls (just in case) > > - map the API call to the correct implementation based on the build > > environment of the caller. > > > > Signed-off-by: Steve Langasek <steve.langasek@xxxxxxxxxxxxx> > > --- > > libselinux/include/selinux/selinux.h | 11 ++++++++++- > > libselinux/src/Makefile | 1 + > > libselinux/src/libselinux.map | 1 + > > libselinux/src/matchpathcon.c | 15 ++++++++++++++- > > 4 files changed, 26 insertions(+), 2 deletions(-) > > > > diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h > > index a0948853..040629c3 100644 > > --- a/libselinux/include/selinux/selinux.h > > +++ b/libselinux/include/selinux/selinux.h > > @@ -1,6 +1,7 @@ > > #ifndef _SELINUX_H_ > > #define _SELINUX_H_ > > > > +#include <stdint.h> I needed <asm/bitsperlong.h> aswell for __BITS_PER_LONG > > #include <sys/types.h> > > #include <stdarg.h> > > > > @@ -521,7 +522,15 @@ extern int matchpathcon_index(const char *path, > > with the same inode (e.g. due to multiple hard links). If so, then > > use the latter of the two specifications based on their order in the > > file contexts configuration. Return the used specification index. */ > > -extern int matchpathcon_filespec_add(ino_t ino, int specind, const char *file); > > +#if _FILE_OFFSET_BITS == 64 One should probably check for existence: #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 > > +typedef uint64_t libselinux_ino_t; > > +#if __BITS_PER_LONG < 64 > > +#define matchpathcon_filespec_add matchpathcon_filespec_add64 > > +#endif > > +#else > > +typedef uint32_t libselinux_ino_t; > > +#endif Is the typedef libselinux_ino_t really necessary, isn't it always just equal to ino_t? > > +extern int matchpathcon_filespec_add(libselinux_ino_t ino, int specind, const char *file); > > > > /* Destroy any inode associations that have been added, e.g. to restart > > for a new filesystem. */ > > diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile > > index d3b981fc..267291aa 100644 > > --- a/libselinux/src/Makefile > > +++ b/libselinux/src/Makefile > > @@ -87,6 +87,7 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi > > -fstack-protector-all --param=ssp-buffer-size=4 -fexceptions \ > > -fasynchronous-unwind-tables -fdiagnostics-show-option \ > > -Werror -Wno-aggregate-return \ > > + -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \ This won't work if CFLAGS are customized during build (e.g. by dpkg). Also utils/ is unaffected. Maybe use something like: libselinux/Makefile: USE_LFS ?= y export USE_LFS libselinux/{src,utils}/Makefile: ifeq ($(USE_LFS),y) override CFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 endif > > $(EXTRA_CFLAGS) > > > > LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=libselinux.map,-z,defs,-z,relro > > diff --git a/libselinux/src/libselinux.map b/libselinux/src/libselinux.map > > index 5e00f45b..88c9b3e5 100644 > > --- a/libselinux/src/libselinux.map > > +++ b/libselinux/src/libselinux.map > > @@ -251,4 +251,5 @@ LIBSELINUX_3.5 { > > global: > > getpidprevcon; > > getpidprevcon_raw; > > + matchpathcon_filespec_add64; > > } LIBSELINUX_3.4; For downstream this seems fine, for upstream this should go into a new LIBSELINUX_3.6 section. > > diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c > > index e44734c3..189e00fb 100644 > > --- a/libselinux/src/matchpathcon.c > > +++ b/libselinux/src/matchpathcon.c > > @@ -195,7 +195,8 @@ static file_spec_t *fl_head; > > * then use the specification that occurs later in the > > * specification array. > > */ > > -int matchpathcon_filespec_add(ino_t ino, int specind, const char *file) > > +int matchpathcon_filespec_add(libselinux_ino_t ino, int specind, > > + const char *file) > > { > > file_spec_t *prevfl, *fl; > > int h, ret; > > @@ -261,6 +262,18 @@ int matchpathcon_filespec_add(ino_t ino, int specind, const char *file) > > return -1; > > } > > > > +#if _FILE_OFFSET_BITS == 64 && __BITS_PER_LONG < 64 > > +/* alias defined in the public header but we undefine it here */ > > +#undef matchpathcon_filespec_add > > + > > +/* ABI backwards-compatible shim for non-LFS 32-bit systems */ Missing extern declaration to avoid a missing-prototype warning. > > +int matchpathcon_filespec_add(unsigned long ino, int specind, Are there 32-bit architectures we like to support where unsigned long is not 4 (but 8) bytes in size? > > + const char *file) > > +{ > > + return matchpathcon_filespec_add64(ino, specind, file); > > +} > > +#endif > > + > > /* > > * Evaluate the association hash table distribution. > > */ > > -- > > 2.40.1 > >