freeradius-server
freeradius-server copied to clipboard
[defect]: link errors when configured with --without-shared-libs
What type of defect/bug is this?
incorrect 3rd party API usage
How can the issue be reproduced?
When I try to build freeradius-server-3.0.27 with the confiugre-option --without-shared-libs, I get link errors for radattr and radeapclient:
$ tar -xf.../freeradius-server-3.0.27.tar.gz
$ cd freeradius-server-3.0.27
$ ./configure --without-shared-libs
...
$ make VERBOSE=1
...
$ LINK build/bin/radeapclient
build/make/jlibtool --silent --mode=link gcc -o build/bin/radeapclient -static build/objs/src/modules/rlm_eap/radeapclient.lo build/objs/src/main/files.lo build/objs/src/main/threads.lo build/objs/src/main/version.lo build/objs/src/main/cb.lo build/objs/src/main/tls.lo build/lib/libfreeradius-radius.la build/lib/libfreeradius-server.la build/lib/libfreeradius-eap.la -lcrypto -lssl -ltalloc -latomic -lpcre -lcap -lnsl -lresolv -ldl -lpthread -lreadline -lcrypto -lssl
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: build/lib/.libs/libfreeradius-server.a(log.o):/home/mkl/tmp/freeradius-server-3.0.27/src/main/log.c:49: multiple definition of `rad_debug_lvl'; build/objs/src/modules/rlm_eap/radeapclient.o:/home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/radeapclient.c:77: first defined here
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: build/lib/.libs/libfreeradius-eap.a(eapcrypto.o): in function `eapsim_calculate_keys':
/home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/eapcrypto.c:85:(.text+0xf4): undefined reference to `fr_sha1_init'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/eapcrypto.c:86:(.text+0x10d): undefined reference to `fr_sha1_update'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/eapcrypto.c:87:(.text+0x118): undefined reference to `fr_sha1_final'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: build/lib/.libs/libfreeradius-eap.a(eapsimlib.o): in function `map_eapsim_basictypes':
/home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/eapsimlib.c:255:(.text+0x35e): undefined reference to `fr_hmac_sha1'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: build/lib/.libs/libfreeradius-eap.a(eapsimlib.o): in function `eapsim_checkmac':
/home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/eapsimlib.c:462:(.text+0x7cb): undefined reference to `fr_hmac_sha1'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: build/lib/.libs/libfreeradius-eap.a(fips186prf.o): in function `fips186_2prf':
/home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/fips186prf.c:134:(.text+0xc2): undefined reference to `fr_sha1_init'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/fips186prf.c:139:(.text+0xf8): undefined reference to `fr_sha1_transform'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/fips186prf.c:143:(.text+0x104): undefined reference to `fr_sha1_final_no_len'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/fips186prf.c:153:(.text+0x179): undefined reference to `fr_sha1_init'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/fips186prf.c:158:(.text+0x1af): undefined reference to `fr_sha1_transform'
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /home/mkl/tmp/freeradius-server-3.0.27/src/modules/rlm_eap/libeap/fips186prf.c:162:(.text+0x1bb): undefined reference to `fr_sha1_final_no_len'
collect2: error: ld returned 1 exit status
make: *** [scripts/boiler.mk:638: build/bin/radeapclient] Error 1
$
The cause is a wrong order of libraries on the linker command line:
.../libfreeradius-radius.la .../libfreeradius-server.la .../libfreeradius-eap.la
libfreeradius-radius.a defines fr_sha1_init, that is needed in libfreeradius-eap.a. The linker has to process libfreeradius-eap.a first to satisfy this undefined symbol.
This can be fixed using this patch:
*** ../freeradius-server-3.0.27.orig/src/modules/rlm_eap/radeapclient.mk 2024-07-08 23:21:42.000000000 +0200
--- src/modules/rlm_eap/radeapclient.mk 2025-06-04 16:03:19.901831694 +0200
***************
*** 5,18 ****
${top_srcdir}/src/main/threads.c \
${top_srcdir}/src/main/version.c
! TGT_PREREQS := libfreeradius-radius.a libfreeradius-server.a
TGT_LDLIBS := $(LIBS)
#
# For future work, if we want radeapclient to become radclient
#
ifneq "$(filter libfreeradius-eap%,${ALL_TGTS})" ""
! TGT_PREREQS += libfreeradius-eap.a
ifneq ($(OPENSSL_LIBS),)
SOURCES += ${top_srcdir}/src/main/cb.c ${top_srcdir}/src/main/tls.c
--- 5,18 ----
${top_srcdir}/src/main/threads.c \
${top_srcdir}/src/main/version.c
! TGT_PREREQS :=
TGT_LDLIBS := $(LIBS)
#
# For future work, if we want radeapclient to become radclient
#
ifneq "$(filter libfreeradius-eap%,${ALL_TGTS})" ""
! TGT_PREREQS += libfreeradius-eap.a libfreeradius-server.a libfreeradius-radius.a
ifneq ($(OPENSSL_LIBS),)
SOURCES += ${top_srcdir}/src/main/cb.c ${top_srcdir}/src/main/tls.c
But now, I get a duplicate symbol error: $ make -k LINK build/bin/radeapclient /usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: build/lib/.libs/libfreeradius-server.a(log.o):/home/mkl/tmp/freeradius-server-3.0.27.mkl/src/main/log.c:49: multiple definition of `rad_debug_lvl'; build/objs/src/modules/rlm_eap/radeapclient.o:/home/mkl/tmp/freeradius-server-3.0.27.mkl/src/modules/rlm_eap/radeapclient.c:77: first defined here collect2: error: ld returned 1 exit status make: *** [scripts/boiler.mk:638: build/bin/radeapclient] Error 1 make: Target 'all' not remade because of errors. $
radattr also fails to link, and this patch fixes that.
*** ../freeradius-server-3.0.27.orig/src/main/radattr.mk 2024-07-08 23:21:42.000000000 +0200
--- src/main/radattr.mk 2025-06-04 15:58:58.197378019 +0200
***************
*** 1,10 ****
TARGET := radattr
SOURCES := radattr.c
! TGT_PREREQS := libfreeradius-server.a libfreeradius-radius.a
ifneq "$(WITH_DHCP)" "no"
! TGT_PREREQS += libfreeradius-dhcp.a
endif
TGT_LDLIBS := $(LIBS)
--- 1,10 ----
TARGET := radattr
SOURCES := radattr.c
! TGT_PREREQS :=
ifneq "$(WITH_DHCP)" "no"
! TGT_PREREQS += libfreeradius-dhcp.a libfreeradius-radius.a libfreeradius-server.a
endif
TGT_LDLIBS := $(LIBS)
A possible fix for the duplicate symbol problem might be to make the variable rad_debug_lvl external in radeapclient.c;
*** ../freeradius-server-3.0.27.orig/src/modules/rlm_eap/radeapclient.c 2024-07-08 23:21:42.000000000 +0200
--- src/modules/rlm_eap/radeapclient.c 2025-06-04 16:02:28.853548098 +0200
***************
*** 74,80 ****
#include <freeradius-devel/tls.h>
#endif
! log_lvl_t rad_debug_lvl = 0;
//TODO: move structures to a header file.
--- 74,80 ----
#include <freeradius-devel/tls.h>
#endif
! extern log_lvl_t rad_debug_lvl;
//TODO: move structures to a header file.
Log output from the FreeRADIUS daemon
-
Relevant log output from client utilities
No response
Backtrace from LLDB or GDB
TBH, this isn't supported. Modern Linux systems are generally almost completely dynamically linked.
Why are you interested in static linking? What platform is this on?
this isn't supported.
When static linking is not supported, configure should not offer this option.
Why are you interested in static linking?
I don't want to use dynamic linking. Dynamic linking introduces new failure modes, but has no benefit for my installation. I am not interested in saving disk space usage nor in saving main memory usage. Dynamic linking has (compared to static linking) more possible failuires and my setup does not benefit from possible code sharing, which can be achieved my dynamic linking.
I compile freeradius for usage in a WLAN test fixture. I need to install different versions of freeradius into different pathes, possibly each installation using a different version of openssl.
I have installed openssl-3.4.0 (compiled as static libraries) into /home/testfixture/openssl-3.4.0.
I have configured freeradius-server-3.0.27 to be installed into /home/testfixture/radius-3.0.27+openssl-3.4.0 with--without-shared-libs and to use libs and inclides from /home/testfixture/openssl-3.4.0.
I want to have a statically linked version, statically linked to openssl, independant of any possible updates on the host system.
I want to build other versions of openssl and other versions of freeradius and install them into different pathes. Everything should co-exist on one host system without interfering each other.
I can achieve this with shared libraries, too, but that is much harder, since I need to get RPATH right on each executable and each shared library, and I must tunnel the required linker option throuch the configure/make-proess into the right Makefiles. I would have to check every executable, that RPATH is correct, and I risk of errors getting along unnoticed.
Just using static libraries is much easier and has less risks of accidential, unnoticed errors.
What platform is this on?
Gentoo linux, x86_64
Dynamic linking introduces new failure modes,
I'm not sure what those are, but OK.
I want to build other versions of openssl and other versions of freeradius and install them into different pathes. Everything should co-exist on one host system without interfering each other.
Other systems do this, they just install the program and any libraries it needs into something like /opt/freeradius-3.2.x/...
So all of OpenSSL, etc. goes into that directory.
Dynamic linking introduces new failure modes,
I'm not sure what those are, but OK.
- failure to find a shared lib
- picking a wrong shared lib
- version incompatibilities between executable and shared lib