[RFC] How to inform users why an executable stack is required

Background

Pointers to internal procedures are implemented using “trampolines”. Trampolines are segments of code that pass host-associated variables to the internal procedures, and they are currently generated on the stack. This means that code on the stack must be executable, which can increase security risks (e.g., enabling buffer overflow attacks). In fact, the GNU Linker in Binutils 2.39 or higher emits a warning message for this, and the LLVM Linker rejects this unless users explicitly allow it.

$ flang src.f90 -fuse-ld=ld
/path/to/ld: warning: src.o: requires executable stack (because the .note.GNU-stack section is executable)
$ flang src.f90 -fuse-ld=lld
ld.lld: error: src.o: requires an executable stack, but -z execstack is not specified
flang-22: error: linker command failed with exit code 1 (use -v to see invocation)

Please note that I have not checked whether Windows has a similar issue.

Problem

The problem is that these messages do not seem sufficient for users to understand what is happening. I suspect users would have the following questions when encountering these messages:

  • Why is an executable stack required? Is it okay to enable it?
  • What should I do to link binaries with lld? flang src.f90 -fuse-ld=lld -z execstack returns another error.

I doubt users can easily find answers to these questions at the moment.

Solutions

I have two possible solutions for this issue.

  1. Implementing a warning flag -Wtrampolines as follows:

    $ flang src.f90 -Wtrampolines
    src.f90:nn:nn: warning: trampoline generated for pointer to inner subprogram 'inn', which requires an executable stack [-Wtrampolines]
        call sub(inn)
                 ^
    src.f90:nn:nn: note: 'inn' is declared here
        subroutine inn
        ^
    /path/to/ld: warning: src.o: requires executable stack (because the .note.GNU-stack section is executable)
    
    • GFortran has the same command-line option, but it is not enabled by default. Considering the background, I believe Flang should enable it by default.
    • However, there is a possibility of false-positive messages being output.
      • I’m thinking of implementing this in the Flang frontend, but it might be better to implement it in the LLVM backend. This is because redundant trampolines are removed during the DSE pass there. (e.g., Compiler Explorer)
  2. Improving documentation

    • Illustrate the following points:
      • The reason why these messages are emitted
      • How to handle this issue
      • The influence of an executable stack
    • IIRC, there are two related documents: the support status and the design document.
      • I’m wondering whether adding the above points to these documents would be appropriate.
    • Clang has an FAQ page. I believe Flang could follow this.
      • My concern is that the current top page of the Flang documentation is not suitable for accommodating a link to an FAQ. Specifically, there are no sections for user guidance. Perhaps, we should rearrange the Table of Contents.

My current plan is to create an FAQ page and include a link to it on the support status page. However, I’m not sure if this is the best approach. I would appreciate your comments on this.

Thanks for the RFC.

I think it would be good to discuss this on one of the community calls if you can make it (or arrange a dedicated meeting at a time more convenient for your time zone, but hopefully with enough overlap with other time zones that enough people attend).

Your proposed solutions look sensible to me. I just have minor comments on details:

  1. I think it would be difficult to implement the warning in the LLVM backend because so far as I know we only have the full diagnostics driver (capable of pretty printing the warning pointing to the offending source as in your example) during flang semantics.
  2. It would be great to see the documentation re-organised as you describe. Some of the pages in the “design documents” section are kind of documentation for users. For example Fortran Extensions supported by Flang — The Flang Compiler and Flang support for REAL(16) math intrinsics — The Flang Compiler and Compiler directives supported by Flang — The Flang Compiler

A better solution would be to implement trampolines on the heap.

2 Likes

I think reorganizing the table of contents into sections primarily directed at end-users and others directed at flang developers is a good idea. I am happy to review related PR’s and/or participate in discussions.

I am not convinced about the usefulness of an FAQ page, but I am not against the idea either. The clang page has only two entries and I am not sure who actually runs into those issues. Something like this may be worth having at the top-level of flang’s documentation page.

Thank you all for your comments.

I think it would be good to discuss this on one of the community calls if you can make it (or arrange a dedicated meeting at a time more convenient for your time zone, but hopefully with enough overlap with other time zones that enough people attend).

I’ll join the next community call. We can discuss this there.

A better solution would be to implement trampolines on the heap.

I agree that implementing trampolines without requiring an executable stack would be better, but I’m not sure how difficult it is. If someone is working on this, we could focus on that approach. However, if it takes some time or no one is working on it, we might have to consider other (tentative) approaches.

See flang/docs/InternalProcedureTrampolines.mdfor a thorough study of the problem. In short, supporting trampolines without needing stack or heap memory to be both writable and executable would be pretty straightforward. Maybe somebody in the LLVM flang community will implement it if you ask them.

Thank you for the discussion in the last call. If I understand correctly, improving the implementation itself is not an urgent task for either the community or me, and I can move forward with creating a new document.