From f65a51afdffeb66298de2eddd661520baa1b1a6a Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 20 Jan 2023 12:30:33 -0700 Subject: [PATCH] Try to link a simple shared object with -Wl,--no-undefined. This only works for gcc-style compilers, which should not be a problem. The source uses environ (FreeBSD) and errno (OpenBSD). --- configure | 65 +++++++++++++++++++++--------------------------- configure.ac | 45 +++++++++++++++++++-------------- m4/visibility.m4 | 2 +- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/configure b/configure index 7f518ee53..0b5011658 100755 --- a/configure +++ b/configure @@ -19828,54 +19828,51 @@ fi # but is incompatible with the sanitizers/fuzzers. # We must set this *before* the library tests. # -if test X"${enable_sanitizer}{enable_fuzzer}" = X"nono"; then - case "$host_os" in - freebsd*|dragonfly*|openbsd*) - # On FreeBSD and Dragonfly, environ is filled in by the - # dynamic loader so we cannot use -Wl,--no-undefined. - # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263265 - # OpenBSD shared libraries don't link explicitly with libc - # which results in undefined references errors. - # Ideally we would link a shared object with -Wl,--no-undefined - # and see if it works but this is not easy in a libtool world. - ;; - *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,--no-undefined" >&5 -printf %s "checking whether the linker accepts -Wl,--no-undefined... " >&6; } -if test ${ax_cv_check_ldflags___Wl___no_undefined+y} +if test -n "$GCC" -a X"${enable_sanitizer}${enable_fuzzer}" = X"nono"; then + # On FreeBSD and Dragonfly, environ is filled in by the dynamic loader + # so -Wl,--no-undefined causes a link error when environ is used. + # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263265 + # We use errno because OpenBSD shared libraries don't explicitly + # link with libc, which can result in undefined reference errors. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the linker accepts -Wl,--no-undefined" >&5 +printf %s "checking the linker accepts -Wl,--no-undefined... " >&6; } +if test ${sudo_cv_var_ld___no_undefined+y} then : printf %s "(cached) " >&6 else case e in #( e) - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS -Wl,--no-undefined" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + sudo_cv_var_ld___no_undefined=no + _CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_prog_compiler_pic" + _LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_prog_compiler_pic -shared -Wl,--no-undefined" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - +#include +extern char **environ; int main (void) { - +int ret = ((long)environ & 0xff) + errno; return ret; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : - ax_cv_check_ldflags___Wl___no_undefined=yes -else case e in #( - e) ax_cv_check_ldflags___Wl___no_undefined=no ;; -esac + sudo_cv_var_ld___no_undefined=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$ax_check_save_flags ;; + CFLAGS="$_CFLAGS" + LDFLAGS="$_LDFLAGS" + + ;; esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl___no_undefined" >&5 -printf "%s\n" "$ax_cv_check_ldflags___Wl___no_undefined" >&6; } -if test x"$ax_cv_check_ldflags___Wl___no_undefined" = xyes -then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_var_ld___no_undefined" >&5 +printf "%s\n" "$sudo_cv_var_ld___no_undefined" >&6; } + if test "$sudo_cv_var_ld___no_undefined" = "yes"; then if test ${LDFLAGS+y} then : @@ -19910,13 +19907,7 @@ else case e in #( esac fi -else case e in #( - e) : ;; -esac -fi - - ;; - esac + fi fi # @@ -32523,7 +32514,7 @@ else case e in #( _CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $lt_prog_compiler_pic" _LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -fpic -shared -Wl,--version-script,./conftest.map" + LDFLAGS="$LDFLAGS $lt_prog_compiler_pic -shared -Wl,--version-script,./conftest.map" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo; diff --git a/configure.ac b/configure.ac index 936901bcd..a556f5afd 100644 --- a/configure.ac +++ b/configure.ac @@ -2455,21 +2455,30 @@ AC_SYS_YEAR2038 # but is incompatible with the sanitizers/fuzzers. # We must set this *before* the library tests. # -if test X"${enable_sanitizer}{enable_fuzzer}" = X"nono"; then - case "$host_os" in - freebsd*|dragonfly*|openbsd*) - # On FreeBSD and Dragonfly, environ is filled in by the - # dynamic loader so we cannot use -Wl,--no-undefined. - # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263265 - # OpenBSD shared libraries don't link explicitly with libc - # which results in undefined references errors. - # Ideally we would link a shared object with -Wl,--no-undefined - # and see if it works but this is not easy in a libtool world. - ;; - *) - AX_CHECK_LINK_FLAG([-Wl,--no-undefined], [AX_APPEND_FLAG([-Wl,--no-undefined], [LDFLAGS])]) - ;; - esac +if test -n "$GCC" -a X"${enable_sanitizer}${enable_fuzzer}" = X"nono"; then + # On FreeBSD and Dragonfly, environ is filled in by the dynamic loader + # so -Wl,--no-undefined causes a link error when environ is used. + # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263265 + # We use errno because OpenBSD shared libraries don't explicitly + # link with libc, which can result in undefined reference errors. + AC_CACHE_CHECK([the linker accepts -Wl,--no-undefined], + [sudo_cv_var_ld___no_undefined], + [ + sudo_cv_var_ld___no_undefined=no + _CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_prog_compiler_pic" + _LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_prog_compiler_pic -shared -Wl,--no-undefined" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include +extern char **environ;]], [[int ret = ((long)environ & 0xff) + errno; return ret;]])], + [sudo_cv_var_ld___no_undefined=yes]) + CFLAGS="$_CFLAGS" + LDFLAGS="$_LDFLAGS" + ] + ) + if test "$sudo_cv_var_ld___no_undefined" = "yes"; then + AX_APPEND_FLAG([-Wl,--no-undefined], [LDFLAGS]) + fi fi # @@ -2482,12 +2491,12 @@ case "$host_os" in hpux*) AC_CACHE_CHECK([whether sys/socket.h needs _XOPEN_SOURCE_EXTENDED for MSG_WAITALL], [sudo_cv_xopen_source_extended], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT -# include ], [int a = MSG_WAITALL; return a;])], +[# include ]], [[int a = MSG_WAITALL; return a;]])], [sudo_cv_xopen_source_extended=no], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#define _XOPEN_SOURCE_EXTENDED AC_INCLUDES_DEFAULT -# include -# include ], [int a = MSG_WAITALL; return a;])], +[# include +# include ]], [[int a = MSG_WAITALL; return a;]])], [sudo_cv_xopen_source_extended=yes], [sudo_cv_xopen_source_extended=error]) ])]) diff --git a/m4/visibility.m4 b/m4/visibility.m4 index 4e07c27ae..48188cdcc 100644 --- a/m4/visibility.m4 +++ b/m4/visibility.m4 @@ -71,7 +71,7 @@ AC_DEFUN([SUDO_SYMBOL_VISIBILITY], [ _CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $lt_prog_compiler_pic" _LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -fpic -shared -Wl,--version-script,./conftest.map" + LDFLAGS="$LDFLAGS $lt_prog_compiler_pic -shared -Wl,--version-script,./conftest.map" AC_LINK_IFELSE([AC_LANG_PROGRAM([[int foo;]], [[]])], [sudo_cv_var_gnu_ld_anon_map=yes]) CFLAGS="$_CFLAGS"