8000 Use symcheck to locate writeable+executable object files by tgross35 · Pull Request #934 · rust-lang/compiler-builtins · GitHub
[go: up one dir, main page]

Skip to content

Use symcheck to locate writeable+executable object files #934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tgross35
Copy link
Contributor
@tgross35 tgross35 commented May 30, 2025

From what I have been able to find, compilers that try to emit object files compatible with a GNU linker appear to add a .note.GNU-stack section if the stack should not be writeable (this section is empty). We never want a writeable stack, so extend the object file check to verify that object files with any executable sections also have this .note.GNU-stack section.

This appears to match what is done by scanelf to emit !WX 1, which is the tool used to create the output in the issue.

Closes: #183

From what I have been able to find, compilers that try to emit object
files compatible with a GNU linker appear to add a `.note.GNU-stack`
section if the stack should not be writeable (this section is empty). We
never want a writeable stack, so extend the object file check to verify
that object files with any executable sections also have this
`.note.GNU-stack` section.

This appears to match what is done by `scanelf` to emit `!WX` [2], which
is the tool used to create the output in the issue.

Closes: rust-lang#183

[1]: https://github.com/gentoo/pax-utils/blob/9ef54b472e42ba2c5479fbd86b8be2275724b064/scanelf.c#L428-L512
@tgross35 tgross35 force-pushed the check-wx-sections branch from ada5714 to 9f44c32 Compare May 30, 2025 02:44
@tgross35
Copy link
Contributor Author

Thumb makes sense to skip as a bare metal target. Note sure about ppc64

@tgross35
Copy link
Contributor Author
tgross35 commented May 30, 2025

Pinging some people who work on PowerPC in rust/llvm to : @daltenty @ecnelises @lei137

I'm trying a small C program on powerpc64, powerpc64le, and powerpc (32). For both powerpc32 and powerpc64le, as well as all other architectures I have tried, there is an empty section named .note.GNU-stack. As I understand it, if this section exists then the linker should not be writeable. However, it doesn't seem like this section is created on powerpc64 .

Is there some other way that a non-writeable stack is indicated, or is this not relevant on the powerpc64 arch?

Repro, note how there is no .note.GNU-stack section only for ppc64:

$ cat a.c
int moo() {
        return 10;
}

$ powerpc64-linux-gnu-gcc -c a.c -o ppc64.o
$ powerpc64le-linux-gnu-gcc -c a.c -o ppc64le.o
$ powerpc-linux-gnu-gcc -c a.c -o ppc32.o

$ powerpc64-linux-gnu-readelf -S ppc64.o
There are 12 section headers, starting at offset 0x268:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000030  0000000000000000  AX       0     0     4
  [ 2] .data             PROGBITS         0000000000000000  00000070
       0000000000000000  0000000000000000  WA       0     0     1
  [ 3] .bss              NOBITS           0000000000000000  00000070
       0000000000000000  0000000000000000  WA       0     0     1
  [ 4] .opd              PROGBITS         0000000000000000  00000070
       0000000000000018  0000000000000000  WA       0     0     8
  [ 5] .rela.opd         RELA             0000000000000000  000001d0
       0000000000000030  0000000000000018   I       9     4     8
  [ 6] .comment          PROGBITS         0000000000000000  00000088
       0000000000000026  0000000000000001  MS       0     0     1
  [ 7] .eh_frame         PROGBITS         0000000000000000  000000b0
       0000000000000034  0000000000000000   A       0     0     4
  [ 8] .rela.eh_frame    RELA             0000000000000000  00000200
       0000000000000018  0000000000000018   I       9     7     8
  [ 9] .symtab           SYMTAB           0000000000000000  000000e8
       00000000000000d8  0000000000000018          10     8     8
  [10] .strtab           STRTAB           0000000000000000  000001c0
       0000000000000009  0000000000000000           0     0     1
  [11] .shstrtab         STRTAB           0000000000000000  00000218
       000000000000004e  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), p (processor specific)

$ powerpc64le-linux-gnu-readelf -S ppc64le.o
There are 11 section headers, starting at offset 0x228:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000030  0000000000000000  AX       0     0     4
  [ 2] .data             PROGBITS         0000000000000000  00000070
       0000000000000000  0000000000000000  WA       0     0     1
  [ 3] .bss              NOBITS           0000000000000000  00000070
       0000000000000000  0000000000000000  WA       0     0     1
  [ 4] .comment          PROGBITS         0000000000000000  00000070
       0000000000000026  0000000000000001  MS       0     0     1
  [ 5] .note.GNU-stack   PROGBITS         0000000000000000  00000096
       0000000000000000  0000000000000000           0     0     1
  [ 6] .eh_frame         PROGBITS         0000000000000000  00000098
       0000000000000034  0000000000000000   A       0     0     4
  [ 7] .rela.eh_frame    RELA             0000000000000000  000001b8
       0000000000000018  0000000000000018   I       8     6     8
  [ 8] .symtab           SYMTAB           0000000000000000  000000d0
       00000000000000d8  0000000000000018           9     8     8
  [ 9] .strtab           STRTAB           0000000000000000  000001a8
       0000000000000009  0000000000000000           0     0     1
  [10] .shstrtab         STRTAB           0000000000000000  000001d0
       0000000000000054  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), p (processor specific)

$ powerpc-linux-gnu-readelf -S ppc32.o
There are 11 section headers, starting at offset 0x1b4:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000024 00  AX  0   0  4
  [ 2] .data             PROGBITS        00000000 000058 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          00000000 000058 000000 00  WA  0   0  1
  [ 4] .comment          PROGBITS        00000000 000058 000026 01  MS  0   0  1
  [ 5] .note.GNU-stack   PROGBITS        00000000 00007e 000000 00      0   0  1
  [ 6] .eh_frame         PROGBITS        00000000 000080 000038 00   A  0   0  4
  [ 7] .rela.eh_frame    RELA            00000000 000154 00000c 0c   I  8   6  4
  [ 8] .symtab           SYMTAB          00000000 0000b8 000090 10      9   8  4
  [ 9] .strtab           STRTAB          00000000 000148 000009 00      0   0  1
  [10] .shstrtab         STRTAB          00000000 000160 000054 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), v (VLE), p (processor specific)

@tgross35
Copy link
Contributor Author

Clang seems to emit the section still, so I guess there could be a chance it is a bug with GCC.

$ clang --target=powerpc64-unknown-linux-gnu -c a.c -o ppc64-clang.o
$ powerpc64-linux-gnu-readelf -S ppc64-clang.o
There are 11 section headers, starting at offset 0x1e8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .strtab           STRTAB           0000000000000000  00000180
       0000000000000065  0000000000000000           0     0     1
  [ 2] .text             PROGBITS         0000000000000000  00000040
       0000000000000014  0000000000000000  AX       0     0     4
  [ 3] .opd              PROGBITS         0000000000000000  00000058
       0000000000000018  0000000000000000  WA       0     0     8
  [ 4] .rela.opd         RELA             0000000000000000  00000138
       0000000000000030  0000000000000018   I      10     3     8
  [ 5] .comment          PROGBITS         0000000000000000  00000070
       0000000000000028  0000000000000001  MS       0     0     1
  [ 6] .note.GNU-stack   PROGBITS         0000000000000000  00000098
       0000000000000000  0000000000000000           0     0     1
  [ 7] .eh_frame         PROGBITS         0000000000000000  00000098
       0000000000000028  0000000000000000   A       0     0     8
  [ 8] .rela.eh_frame    RELA             0000000000000000  00000168
       0000000000000018  0000000000000018   I      10     7     8
  [ 9] .llvm_addrsig     LLVM_ADDRSIG     0000000000000000  00000180
       0000000000000000  0000000000000000   E      10     0     1
  [10] .symtab           SYMTAB           0000000000000000  000000c0
       0000000000000078  0000000000000018           1     3     8
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), p (processor specific)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to c 5A63 omment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Parts of libcompiler_builtins are compiled as WX
1 participant
0