bug-gnulib
[Top][All Lists]
Advanced

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

Re: selinux: insufficient M4 detection with building static binaries


From: Bruno Haible
Subject: Re: selinux: insufficient M4 detection with building static binaries
Date: Sun, 07 Apr 2019 13:08:11 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-141-generic; KDE/5.18.0; x86_64; ; )

Hi Assaf,

>    --- se-good.c ---
>    extern char setfilecon();
>    int main(){return setfilecon();}
> 
>    --- se-bad.c ---
>    extern char matchpathcon_init_prefix();
>    int main(){return matchpathcon_init_prefix();}
> 
> 
>    $ gcc -o 1 -static se-good.c -lselinux && echo ok
>    ok
> 
>    $ gcc -o 1 -static se-bad.c -lselinux

When a shared library depends on other shared libraries, you don't have to
specify the dependencies; ELF cares about that. But when you are linking
statically, you need the dependencies. An installed .la file would provide
this information, but unfortunately the distros don't ship a libselinux.la
file. So you have to put the knowledge about the dependencies into the
.m4 file.

In this case:

$ ldd /lib/x86_64-linux-gnu/libselinux.so.1
        linux-vdso.so.1 =>  (0x00007ffda95ee000)
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f9f1d00a000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9f1ce06000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9f1ca3c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f9f1d49c000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 
(0x00007f9f1c81f000)

So, you see, it depends on -lpcre and -lpthread.

$ gcc -o 1 -static se-bad.c -lselinux
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libselinux.a(label_file.o):
 In function `closef':
(.text+0x136): undefined reference to `pcre_free'
...

pcre_free is contained in libpcre.

$ gcc -o 1 -static se-bad.c -lselinux -lpcre
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libselinux.a(load_policy.o):
 In function `selinux_mkload_policy':
(.text+0x11f): undefined reference to `sepol_policy_kern_vers_max'
...

sepol_policy_kern_vers_max is contained in libsepol.

$ gcc -o 1 -static se-bad.c -lselinux -lpcre -lsepol
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libpcre.a(libpcre_la-pcre_jit_compile.o):
 In function `sljit_generate_code':
(.text+0x6d1): undefined reference to `pthread_mutex_lock'
...

pthread_mutex_lock is contained in libpthread.

$ gcc -o 1 -static se-bad.c -lselinux -lpcre -lsepol -lpthread
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libselinux.a(seusers.o):
 In function `getseuserbyname':
(.text+0x574): warning: Using 'getgrouplist' in statically linked applications 
requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libselinux.a(seusers.o):
 In function `getseuserbyname':
(.text+0x546): warning: Using 'getgrnam_r' in statically linked applications 
requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libselinux.a(seusers.o):
 In function `getseuserbyname':
(.text+0x433): warning: Using 'getpwnam_r' in statically linked applications 
requires at runtime the shared libraries from the glibc version used for linking
$ echo $?
0

So, these are the libraries that are needed. Apparently libselinux is
built in such a way that it needs libdl in the shared build, but libsepol
in the static build.

> Perhaps it used to be that "matchpathcon_init_prefix" was optional
> when building with selinux?
> 
> It seems that now it is required.

matchpathcon_init_prefix is declared in gnulib's lib/se-selinux.in.h
since the beginning. It's not a later addition.

> tweaking m4/selinux combinations is beyond my comfort zone...
> the following hack at least avoids the issue by detecting that
> linking with "matchpathcon_init_prefix" fails, thus automatically
> disabling SELinux for static builds:
> 
> ---
> diff --git a/m4/selinux-selinux-h.m4 b/m4/selinux-selinux-h.m4
> index 8bbbf0535..a35ce6cf0 100644
> --- a/m4/selinux-selinux-h.m4
> +++ b/m4/selinux-selinux-h.m4
> @@ -56,12 +56,13 @@ AC_DEFUN([gl_LIBSELINUX],
>       AC_SEARCH_LIBS([setfilecon], [selinux],
>                      [test "$ac_cv_search_setfilecon" = "none required" ||
>                       LIB_SELINUX=$ac_cv_search_setfilecon])
> +    AC_CHECK_LIB([selinux], [matchpathcon_init_prefix], [], [])
>       LIBS=$gl_save_LIBS
>     fi
>     AC_SUBST([LIB_SELINUX])
> 
>     # Warn if SELinux is found but libselinux is absent;
> -  if test "$ac_cv_search_setfilecon" = no; then
> +  if test "$ac_cv_search_setfilecon" = no || test 
> "$ac_cv_lib_selinux_matchpathcon_init_prefix" = no ; then
>       if test "$host" = "$build" && test -d /selinux; then
>         AC_MSG_WARN([This system supports SELinux but libselinux is 
> missing.])
>         AC_MSG_WARN([AC_PACKAGE_NAME will be compiled without SELinux 
> support.])
> ---

It would be better to instead set LIB_SELINUX to
"-lselinux -lpcre -lsepol -lpthread" (in the static case).

Bruno




reply via email to

[Prev in Thread] Current Thread [Next in Thread]