package/libxcrypt: make available only with glibc

libxcrypt has been added as a replacement for the libcrypt
implementation that was part of glibc, but dropped from glibc starting
from version 2.39.

However, libxcrypt was made available for all C libraries, and this is
unfortunately causing some problems as it can clash with the libcrypt
implementation provided by the C library.

In particular, linux-pam has been consistently failing with uclibc, in
BR2_PER_PACKAGE_DIRECTORIES=y builds, with the following build
failure:

opasswd.c: In function 'compare_password':
opasswd.c:133:27: error: invalid application of 'sizeof' to incomplete type 'struct crypt_data'

What happens is relatively tricky, but let's try to break it down:

- uclibc-ng install a stub libcrypt.a (no shared variant, as for
  shared libraries, everything is in libc.so), and crypt.h

- libxcrypt installs libcrypt.so.* and crypt.h

So there is no "clash" on the library itself, but there is a clash on
the header file.

Since we're using BR2_PER_PACKAGE_DIRECTORIES=y, when building
linux-pam, we are creating the per-package STAGING_DIR by copying the
STAGING_DIR of linux-pam dependencies, i.e both the libxcrypt
STAGING_DIR and the uclibc-ng STAGING_DIR. But the latter ends up
being copied last, which means that at the end of the day, we have in
the per-package STAGING_DIR of linux-pam:

- The libcrypt.so from libxcrypt
- The crypt.h header from uclibc-ng
- The libcrypt.a from uclibc-ng

When the ./configure script of linux-pam tests whether the library has
crypt_r(), it concludes that yes it's available: and indeed
libcrypt.so from libxcrypt has it.

So it tries to use 'struct crypt_data' and 'crypt_r()', but those are
not supported in uClibc-ng, and so cannot be found in the <crypt.h>
header. So even if the ./configure script and the linux-pam code has
some logic to fallback to crypt() if crypt_r() isn't available, this
fallback doesn't trigger because the installed libcrypt.so does have
crypt_r().

Basically what happens is that uclibc-ng + libxcrypt is a combo that
violates a golden rule of our BR2_PER_PACKAGE_DIRECTORIES=y
implementation: packages shouldn't overwrite files from each other.

To avoid this situation, we make libxcrypt only installable on
glibc. This isn't a problem because as of today, BR2_PACKAGE_LIBXCRYPT
is always selected "if BR2_TOOLCHAIN_USES_GLIBC".

It should be noted though that the case of an older glibc (which still
had its own internal libcrypt) + libxcrypt continues to exist. It's
less likely to cause trouble though, as the libcrypt implementations
are much more similar.

Fixes:

  http://autobuild.buildroot.net/results/560f66b0311d02dc884732221d6870ae3c38067c/

Note: we do not add a Config.in comment for this glibc dependency,
because libxcrypt really is a "replacement" library to fill in the
void left by libcrypt's removal from glibc. There isn't realy a point
showing "libxcrypt needs a toolchain w/ glibc", because with musl or
uclibc-ng, the libcrypt functionality is directly part of the C
library.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Julien Olivain <ju.o@free.fr>
(cherry picked from commit 5c0a91f7293523254e9c48667df4468370fda58d)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
This commit is contained in:
Thomas Petazzoni 2025-01-08 22:34:07 +01:00 committed by Peter Korsgaard
parent 1889815afc
commit 7fd80897a1

View File

@ -1,5 +1,6 @@
config BR2_PACKAGE_LIBXCRYPT
bool "libxcrypt"
depends on BR2_TOOLCHAIN_USES_GLIBC
help
libxcrypt is a modern library for one-way hashing
of passwords. It supports a wide variety of both