Re: [PATCH] Always build for LFS mode on 32-bit archs.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Steve Langasek <vorlon@xxxxxxxxxx> writes:

> Thanks again for the feedback.
>
> Since you weren't cc:ed on my earlier email, I'd like to pull out my comment
> at the top of the thread:
>
>   As this problem has been discovered rather late in our transition process, I
>   have a bit of a time crunch on my side which is not your problem, but I
>   would ask that whether or not the patch is ready to land, we reach a
>   consensus ASAP on:
>
>     - whether it is acceptable to introduce a new entry point for this on
>       32-bit architectures
>     - the name this new entry point should use (including symbol version)
>     - that it is acceptable to upstream that we proceed on implementing this
>       at the distro level in advance of the patch landing upstream.
>
> Since all of your comments have been about the mechanics of the patch
> landing, am I able to take it as agreed that libselinux will add a new entry
> point of matchpathcon_filespec_add64@LIBSELINUX_3.6 in the next release, and
> the rest is details?

Technical detail: next release will be 3.7 therefore I'd expect
matchpathcon_filespec_add64@LIBSELINUX_3.7



> On Tue, Feb 27, 2024 at 06:13:47PM +0100, Christian Göttsche wrote:
>> On Tue, 27 Feb 2024 at 08:00, Steve Langasek <vorlon@xxxxxxxxxx> wrote:
>> >
>> > Thanks for the feedback.
>> >
>> > On Mon, Feb 26, 2024 at 06:52:10PM +0100, Christian Göttsche wrote:
>> > > > > +#include <stdint.h>
>
>> > > I needed <asm/bitsperlong.h> aswell for __BITS_PER_LONG
>
>> > Can you tell me about the platform you were building on?  In my tests, the
>> > code with this patch behaved as intended on Ubuntu 24.04 pre-release with
>> > glibc 2.38, on both armhf and amd64, with no additional includes required.
>
>> Debian sid.
>
> Ok.  https://codesearch.debian.net/search?q=%3Casm%2Fbitsperlong.h%3E&literal=1
> shows it's uncommon to include asm/bitsperlong directly from userspace
> packages, but not unprecedented, so I'll go ahead and make that change.
>
>> > > > > +#if _FILE_OFFSET_BITS == 64
>
>> > > One should probably check for existence:
>
>> > > #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
>
>> > Should we not consider it an error if this is not defined?  I can't think of
>> > any reason why _FILE_OFFSET_BITS would legitimately be missing and in my
>> > view it's ambiguous what we should do in this circumstance.  Using the
>> > define without checking for existence first implicitly gives an error if
>> > it's missing.  If preferred, we could be explicit as in:
>> >
>> > #if !defined(_FILE_OFFSET_BITS)
>> > #error [...]
>> > #endif
>> > #if _FILE_OFFSET_BITS == 64
>> > [...]
>
>> During my testing yesterday _FILE_OFFSET_BITS was not defined by
>> default (gcc-13/gcc-14/clang-18 on Debian sid).
>
> It occurs to me that I only did a test build of libselinux itself with this
> change, and maybe you're trying to build other software against it and
> therefore running into the issue when including this public header.  Ok,
> 'defined &&' it is.
>
>> > > > > +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?
>
>> > When _FILE_OFFSET_BITS == 64, ino_t is a 64-bit type and we need to
>> > explicitly declare a 32-bit type for the compatibility interface.  From
>> > sys/stat.h:
>
>> > # ifndef __ino_t_defined
>> > #  ifndef __USE_FILE_OFFSET64
>> > typedef __ino_t ino_t;
>> > #  else
>> > typedef __ino64_t ino_t;
>> > #  endif
>> > #  define __ino_t_defined
>> > # endif
>
>> But isn't this the identical logic as for libselinux_ino_t?
>> If _FILE_OFFSET_BITS is defined to be 64 libselinux_ino_t is
>> typedef'ed to uint64_t and ino_t should also be a 64-bit integer.
>> If _FILE_OFFSET_BITS is not 64 libselinux_ino_t is typedef'ed to
>> uint32_t and ino_t should also be a 32-bit integer.
>
> You're right, I overlooked this when refactoring based on Kees's feedback in
> <https://lore.kernel.org/selinux/Zdrh%2FeuXdvdWlVSp@xxxxxxxxxxxxxxx/T/#m1d767f13e043e662555f6b8d8ddbffe033435d33>.
>
> We want the entry point exposed to the caller to always be the one using the
> same ino_t size as the rest of the calling code.  So there's no need for
> this extra typedef; fixed.
>
>> > > > > 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
>
>> > Thanks, I'm happy to amend the patch to do that (but will wait to converge
>> > on the other points above before I resubmit).
>
> As an aside here, it doesn't actually matter if the utils are built with LFS
> support for this purpose; the point is to make sure the library isn't broken
> for callers, whether they have LFS enabled or not.  But as long as we're
> changing the library anyway to always be LFS-compatible, there's no harm in
> also turning it on for the utils.
>
> Attached an updated patch which I think addresses all your feedback.
>
> -- 
> 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
> From fb2e5ecaa84a2bb3d9f1f3946968add62e0ce5df 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/Makefile                  |  6 ++++++
>  libselinux/include/selinux/selinux.h |  5 +++++
>  libselinux/src/Makefile              |  2 ++
>  libselinux/src/libselinux.map        |  5 +++++
>  libselinux/src/matchpathcon.c        | 16 ++++++++++++++++
>  libselinux/utils/Makefile            |  2 ++
>  6 files changed, 36 insertions(+)
>
> diff --git a/libselinux/Makefile b/libselinux/Makefile
> index 6d9e2736..a50b6491 100644
> --- a/libselinux/Makefile
> +++ b/libselinux/Makefile
> @@ -34,6 +34,12 @@ PCRE_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(PCRE_MODULE))
>  PCRE_LDLIBS := $(shell $(PKG_CONFIG) --libs $(PCRE_MODULE))
>  export PCRE_MODULE PCRE_CFLAGS PCRE_LDLIBS
>  
> +USE_LFS ?= y
> +ifeq ($(USE_LFS),y)
> +	LFS_CFLAGS := -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
> +endif
> +export LFS_CFLAGS
> +
>  OS := $(shell uname)
>  export OS
>  
> diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
> index a0948853..080b486c 100644
> --- a/libselinux/include/selinux/selinux.h
> +++ b/libselinux/include/selinux/selinux.h
> @@ -1,8 +1,10 @@
>  #ifndef _SELINUX_H_
>  #define _SELINUX_H_
>  
> +#include <stdint.h>
>  #include <sys/types.h>
>  #include <stdarg.h>
> +#include <asm/bitsperlong.h>
>  
>  #ifdef __cplusplus
>  extern "C" {
> @@ -521,6 +523,9 @@ 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. */
> +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && __BITS_PER_LONG < 64
> +#define matchpathcon_filespec_add matchpathcon_filespec_add64
> +#endif
>  extern int matchpathcon_filespec_add(ino_t ino, int specind, const char *file);
>  
>  /* Destroy any inode associations that have been added, e.g. to restart
> diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
> index d3b981fc..9580cce8 100644
> --- a/libselinux/src/Makefile
> +++ b/libselinux/src/Makefile
> @@ -89,6 +89,8 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi
>            -Werror -Wno-aggregate-return \
>            $(EXTRA_CFLAGS)
>  
> +override CFLAGS += $(LFS_CFLAGS)
> +
>  LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=libselinux.map,-z,defs,-z,relro
>  
>  ifeq ($(OS), Darwin)
> diff --git a/libselinux/src/libselinux.map b/libselinux/src/libselinux.map
> index 5e00f45b..5176c8a9 100644
> --- a/libselinux/src/libselinux.map
> +++ b/libselinux/src/libselinux.map
> @@ -252,3 +252,8 @@ LIBSELINUX_3.5 {
>      getpidprevcon;
>      getpidprevcon_raw;
>  } LIBSELINUX_3.4;
> +
> +LIBSELINUX_3.6 {
> +  global:
> +    matchpathcon_filespec_add64;
> +} LIBSELINUX_3.5;
> diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c
> index e44734c3..f8ee4b4b 100644
> --- a/libselinux/src/matchpathcon.c
> +++ b/libselinux/src/matchpathcon.c
> @@ -261,6 +261,22 @@ 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 */
> +
> +extern int matchpathcon_filespec_add(unsigned long ino, int specind,
> +                                     const char *file);
> +
> +int matchpathcon_filespec_add(unsigned long ino, int specind,
> +                              const char *file)
> +{
> +	return matchpathcon_filespec_add64(ino, specind, file);
> +}
> +#endif
> +
>  /*
>   * Evaluate the association hash table distribution.
>   */
> diff --git a/libselinux/utils/Makefile b/libselinux/utils/Makefile
> index f3cedc11..0d7095b1 100644
> --- a/libselinux/utils/Makefile
> +++ b/libselinux/utils/Makefile
> @@ -36,6 +36,8 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi
>            -Werror -Wno-aggregate-return -Wno-redundant-decls -Wstrict-overflow=5 \
>            $(EXTRA_CFLAGS)
>  
> +override CFLAGS += $(LFS_CFLAGS)
> +
>  ifeq ($(OS), Darwin)
>  override CFLAGS += -I/opt/local/include -I../../libsepol/include
>  override LDFLAGS += -L../../libsepol/src -undefined dynamic_lookup
> -- 
> 2.40.1






[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux