Compiling with musl gives: 'Error relocating - secure_getenv: symbol not found'

3.3k views Asked by At

I am trying to compile a simple C program using a musl toolchain v1.2.1 on x86_64 Debian.

The program secgetenv.c is as follows:

#define _GNU_SOURCE
#include <stdlib.h> 
#include <stdio.h>

int main()
{
    char *res;

    res = secure_getenv("TEST_ENV_VAR");

    fprintf(stdout, "%s\n", res);

    return 0;
}

Compiling executes without error. However running ldd reveals that the symbol secure_getenv is not found:

$ musl-ldd secgetenv-musl 
    /lib/ld-musl-x86_64.so.1 (0x7f7872779000)
    libc.so => /lib/ld-musl-x86_64.so.1 (0x7f7872779000)
Error relocating secgetenv-musl: secure_getenv: symbol not found

musl added support for secure_getenv in an earlier patch, and I do see a declaration in /usr/local/x86_64-linux-musl/include/stdlib.h:

#ifdef _GNU_SOURCE
...
char *secure_getenv(const char *);
...
#endif

with a corresponding definition in src/env/secure_getenv.c:

#define _GNU_SOURCE
#include <stdlib.h>
#include "libc.h"

char *secure_getenv(const char *name)
{
    return libc.secure ? NULL : getenv(name);
}

Additionally, musl's libc.so has the symbol defined:

$ readelf -s /usr/local/x86_64-linux-musl/lib/libc.so | grep secure
  1461: 0000000000020e0d    17 FUNC    GLOBAL DEFAULT    8 secure_getenv
   358: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS secure_getenv.c
  2275: 0000000000020e0d    17 FUNC    GLOBAL DEFAULT    8 secure_getenv

I have tried setting LD_LIBRARY_PATH to point to /usr/local/x86_64-linux-musl/lib (where musl's libc resides)., but that didn't seem to fix anything. I have tried a few other compiler options, but nothing seems to fix it. Am I doing something wrong? How can I resolve this issue?


I thought it might be useful if I added how I compiled, so here is the verbose output:

$ /usr/local/bin/x86_64-linux-musl-gcc -v -o secgetenv-musl secgetenv.c -fPIC -ggdb
Using built-in specs.
COLLECT_GCC=/usr/local/bin/x86_64-linux-musl-gcc
COLLECT_LTO_WRAPPER=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/lto-wrapper
Target: x86_64-linux-musl
Configured with: ../src_gcc/configure --enable-languages=c,c++ --enable-languages=c,c++ --enable-default-pie --disable-bootstrap --disable-assembly --disable-werror --target=x86_64-linux-musl --prefix= --libdir=/lib --disable-multilib --with-sysroot=/x86_64-linux-musl --enable-tls --disable-libmudflap --disable-libsanitizer --disable-gnu-indirect-function --disable-libmpx --enable-libstdcxx-time=rt --with-build-sysroot=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_sysroot AR_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/ar AS_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/gas/as-new LD_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/ld/ld-new NM_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/nm-new OBJCOPY_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/objcopy OBJDUMP_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/objdump RANLIB_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/ranlib READELF_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/readelf STRIP_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/strip-new --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu
Thread model: posix
gcc version 9.2.0 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
 /usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/cc1 -quiet -v -iprefix /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/ -isysroot /usr/local/bin/../x86_64-linux-musl secgetenv.c -quiet -dumpbase secgetenv.c -mtune=generic -march=x86-64 -auxbase secgetenv -ggdb -version -fPIC -o /tmp/cczjeoUa.s
GNU C17 (GCC) version 9.2.0 (x86_64-linux-musl)
    compiled by GNU C version 8.3.0, GMP version 6.1.2, MPFR version 4.0.2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/bin/../x86_64-linux-musl/usr/local/include"
ignoring duplicate directory "/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/include"
ignoring nonexistent directory "/usr/local/bin/../x86_64-linux-musl/usr/include"
ignoring duplicate directory "/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-linux-musl/9.2.0/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/include
 /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/include
End of search list.
GNU C17 (GCC) version 9.2.0 (x86_64-linux-musl)
    compiled by GNU C version 8.3.0, GMP version 6.1.2, MPFR version 4.0.2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 02d33dfe51251a8723bc0ce5bbca8406
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
 /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/bin/as -v --64 -o /tmp/ccMKBInY.o /tmp/cczjeoUa.s
GNU assembler version 2.33.1 (x86_64-linux-musl) using BFD version (GNU Binutils) 2.33.1
COMPILER_PATH=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/:/usr/local/bin/../libexec/gcc/:/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/bin/
LIBRARY_PATH=/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/:/usr/local/bin/../lib/gcc/:/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/:/usr/local/bin/../x86_64-linux-musl/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
 /usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/collect2 -plugin /usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/liblto_plugin.so -plugin-opt=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccjHWTRL.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/usr/local/bin/../x86_64-linux-musl --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib/ld-musl-x86_64.so.1 -pie -o secgetenv-musl /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/Scrt1.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/crti.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/crtbeginS.o -L/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0 -L/usr/local/bin/../lib/gcc -L/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib -L/usr/local/bin/../x86_64-linux-musl/lib /tmp/ccMKBInY.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/crtendS.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
2

There are 2 answers

0
peachykeen On BEST ANSWER

/lib/ld-musl-x86_64.so.1 symlinked to /lib/x86_64-linux-musl/libc.so which didn't have the symbol defined. This libc was introduced when I installed musl-tools or something like that. It uses musl version 1.1.21 which does not have the secure_getenv patch required to get rid of this error. Symlinking ld to a more recent musl libc.so that I got when installing musl-cross-make fixed my problem.

2
John Bollinger On

However running ldd reveals that the symbol secure_getenv is not found:

$ musl-ldd secgetenv-musl 
    /lib/ld-musl-x86_64.so.1 (0x7f7872779000)
    libc.so => /lib/ld-musl-x86_64.so.1 (0x7f7872779000)
Error relocating secgetenv-musl: secure_getenv: symbol not found

ldd appears to be revealing more than that the symbol is not found. It seems to show that something, perhaps musl-ldd itself, is seriously broken. The output indicates that libc.so is being resolved not to MUSL's libc, nor even the system's default libc, but to MUSL's runtime dynamic linker. Naturally, that does not provide the wanted symbol itself.

If the program runs as expected despite the complaint from musl-ldd, then the problem is most likely in musl-ldd. If the program does not run as expected (maybe it reports the same relocation error when you try) then the issue is probably in your copy of MUSL, and specifically in its runtime dynamic linker, /lib/ld-musl-x86_64.so.1.

Addendum:

Supposing that comments on this answer are correct that the MUSL program interpreter contains a copy of the C library, it still follows that there is a serious problem here, either in musl-ldd or in your copy of the library, specifically in /lib/ld-musl-x86_64.so.1. For example, the latter may be out of sync with the library. Possibly such a problem could be the result of having components of two or more different MUSL installations present at the same time, or of having a MUSL compiler toolchain that is out of sync with the installed version of MUSL.