From 7fd80897a121329e2c8238ad629ae90e470218e2 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 8 Jan 2025 22:34:07 +0100 Subject: [PATCH] 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 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 Signed-off-by: Julien Olivain (cherry picked from commit 5c0a91f7293523254e9c48667df4468370fda58d) Signed-off-by: Peter Korsgaard --- package/libxcrypt/Config.in | 1 + 1 file changed, 1 insertion(+) diff --git a/package/libxcrypt/Config.in b/package/libxcrypt/Config.in index 57ae8f67a3..38c75b5e63 100644 --- a/package/libxcrypt/Config.in +++ b/package/libxcrypt/Config.in @@ -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