diff mbox

Don't assume __secure_getenv is available

Message ID 1493319051-25795-1-git-send-email-blomqvist.janne@gmail.com
State New
Headers show

Commit Message

Janne Blomqvist April 27, 2017, 6:50 p.m. UTC
Glibc 2.17 made __secure_getenv an officially supported function, and
renamed it secure_getenv. The libgfortran configure has checked for
both of these, per
https://sourceware.org/glibc/wiki/Tips_and_Tricks/secure_getenv.

Unfortunately, while the dynamical library (libc.so) retains the
__secure_getenv symbol for backwards compatibility, the static library
(libc.a) does not. This means that a libgfortran.a compiled against an
older glibc will not work if one tries to link against a newer
libc.a. This creates problems for providing gfortran binary
distributions that work on as many target systems as possible.

Thus, retain the support for __secure_getenv but call it only via a
weak reference.

Regtested on x86_64-pc-linux-gnu, Ok for trunk, 7.x when it reopens,
6, 5?

2017-04-27  Janne Blomqvist  <jb@gcc.gnu.org>

	* libgfortran.h: HAVE_SECURE_GETENV: Don't check
	HAVE___SECURE_GETENV.
	* environ/runtime.c (secure_getenv): Use __secure_getenv via a
        weak reference.
	* Makefile.in: Regenerated.
---
 libgfortran/Makefile.in       |  5 +++--
 libgfortran/libgfortran.h     |  4 +---
 libgfortran/runtime/environ.c | 11 +++++++++++
 3 files changed, 15 insertions(+), 5 deletions(-)

Comments

Thomas Schwinge May 12, 2017, 7:23 a.m. UTC | #1
Hi!

On Thu, 27 Apr 2017 21:50:51 +0300, Janne Blomqvist <blomqvist.janne@gmail.com> wrote:
> [...], retain the support for __secure_getenv but call it only via a
> weak reference.
> 
> Regtested on x86_64-pc-linux-gnu, Ok for trunk, 7.x when it reopens,
> 6, 5?

Hmm, how has this been tested?  Because:

> --- a/libgfortran/runtime/environ.c
> +++ b/libgfortran/runtime/environ.c

>  #ifdef FALLBACK_SECURE_GETENV
> +
> +#if SUPPORTS_WEAKREF && defined(HAVE___SECURE_GETENV)
> +static char* weak_secure_getenv (const char*)
> +  __attribute__((__weakref__("__secure_gettime")));
> +#endif

"gettime" vs. "getenv"?  ;-)


Grüße
 Thomas
Janne Blomqvist May 12, 2017, 7:26 a.m. UTC | #2
On Fri, May 12, 2017 at 10:23 AM, Thomas Schwinge
<thomas@codesourcery.com> wrote:
> Hi!
>
> On Thu, 27 Apr 2017 21:50:51 +0300, Janne Blomqvist <blomqvist.janne@gmail.com> wrote:
>> [...], retain the support for __secure_getenv but call it only via a
>> weak reference.
>>
>> Regtested on x86_64-pc-linux-gnu, Ok for trunk, 7.x when it reopens,
>> 6, 5?
>
> Hmm, how has this been tested?  Because:
>
>> --- a/libgfortran/runtime/environ.c
>> +++ b/libgfortran/runtime/environ.c
>
>>  #ifdef FALLBACK_SECURE_GETENV
>> +
>> +#if SUPPORTS_WEAKREF && defined(HAVE___SECURE_GETENV)
>> +static char* weak_secure_getenv (const char*)
>> +  __attribute__((__weakref__("__secure_gettime")));
>> +#endif
>
> "gettime" vs. "getenv"?  ;-)

Oops. I'm not at my gcc development box now, please consider a patch
to fix this pre-approved.

As for testing, I regtested, but my gcc development machine has glibc
2.23 which has secure_getenv so it doesn't exercise the fallback
path..
diff mbox

Patch

diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index 05b183d..4914a6f 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -137,8 +137,9 @@  am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
 	$(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
 	$(top_srcdir)/acinclude.m4 $(top_srcdir)/../config/acx.m4 \
 	$(top_srcdir)/../config/no-executables.m4 \
-	$(top_srcdir)/../config/math.m4 $(top_srcdir)/../libtool.m4 \
-	$(top_srcdir)/configure.ac
+	$(top_srcdir)/../config/math.m4 \
+	$(top_srcdir)/../config/ax_check_define.m4 \
+	$(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index cfa4fcf..9d9d117 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -808,9 +808,7 @@  internal_proto(get_unformatted_convert);
 
 /* Secure getenv() which returns NULL if running as SUID/SGID.  */
 #ifndef HAVE_SECURE_GETENV
-#ifdef HAVE___SECURE_GETENV
-#define secure_getenv __secure_getenv
-#elif defined(HAVE_GETUID) && defined(HAVE_GETEUID) \
+#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) \
   && defined(HAVE_GETGID) && defined(HAVE_GETEGID)
 #define FALLBACK_SECURE_GETENV
 extern char *secure_getenv (const char *);
diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c
index bf02188..969dcdf 100644
--- a/libgfortran/runtime/environ.c
+++ b/libgfortran/runtime/environ.c
@@ -37,9 +37,20 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    provided. */
 
 #ifdef FALLBACK_SECURE_GETENV
+
+#if SUPPORTS_WEAKREF && defined(HAVE___SECURE_GETENV)
+static char* weak_secure_getenv (const char*)
+  __attribute__((__weakref__("__secure_gettime")));
+#endif
+
 char *
 secure_getenv (const char *name)
 {
+#if SUPPORTS_WEAKREF && defined(HAVE__SECURE_GETENV)
+  if (weak_secure_getenv)
+    return weak_secure_getenv (name);
+#endif
+
   if ((getuid () == geteuid ()) && (getgid () == getegid ()))
     return getenv (name);
   else