Fortran and executable stack

The Fortran standard has a feature that basically allows creating closures, here’s an example:

program main
  real :: a, integral
  a = 0.4

  integral = integrate(f, a=0.0, b=1.0)
  print '("integral is ", g0)', integral

contains

  function f(x)
    real :: f, x
    f = sin(x + a)  ! parameter `a` from main scope
  end function f

end program

Now, gfortran implements this feature as it does for C nested functions: using a trampoline that needs the stack to be executable. The difference is that nested functions are a nonstandard GNU extension and probably very rarely used, but in Fortran this pattern is quite common.

The problem is that since NixOS 26.05 (glibc 2.42), the stack of a binary loading such a shared library is not made executable automatically, not anymore. If the library is linked against the binary it seems ok, but if you dlopen it from some Python bindings, for example, you get:

OSError: ./blabla.so: cannot enable executable stack as shared object requires: Invalid argument

The manual suggests setting this variable GLIBC_TUNABLES=glibc.rtld.execstack=2, but it does not look like a permanent solution. What is the proper way to do this?

1 Like

I’ve found out there’s a gcc codegen option -ftrampoline-impl=heap to use a dynamic allocation to set up the trampoline. So, if you can build from source, then you can avoid the executable stack entirely.

Otherwise, I think the only way is to use mprotect(2) to make the stack executable yourself, prior to loading the library.

2 Likes