Skip to content

[ELF] Error for executable .note.GNU-stack unless -z execstack or -r #124068

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

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Jan 23, 2025

.note.GNU-stack with the SHF_EXECINSTR flag requires an executable
stack. This is exceedingly rare. We report an error to force
the user to explicitly request an executable stack.

Close #121234

Created using spr 1.3.5-bogner
@llvmbot
Copy link
Member

llvmbot commented Jan 23, 2025

@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: Fangrui Song (MaskRay)

Changes

Close #121234


Full diff: https://github.com/llvm/llvm-project/pull/124068.diff

2 Files Affected:

  • (modified) lld/ELF/InputFiles.cpp (+8-1)
  • (modified) lld/test/ELF/gnustack.s (+26-9)
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index c44773d0b7dabe..f34de787a16379 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1026,8 +1026,15 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
     // explicitly told to do otherwise (by -z execstack). Because the stack
     // executable-ness is controlled solely by command line options,
     // .note.GNU-stack sections are simply ignored.
-    if (name == ".note.GNU-stack")
+    if (name == ".note.GNU-stack") {
+      if ((sec.sh_flags & SHF_EXECINSTR) && !ctx.arg.relocatable &&
+          ctx.arg.zGnustack != GnuStackKind::Exec) {
+        Err(ctx) << this
+                 << ": requires an executable stack, but -z execstack is not "
+                    "specified";
+      }
       return &InputSection::discarded;
+    }
 
     // Object files that use processor features such as Intel Control-Flow
     // Enforcement (CET) or AArch64 Branch Target Identification BTI, use a
diff --git a/lld/test/ELF/gnustack.s b/lld/test/ELF/gnustack.s
index 828e09328c892c..29e81538b6cab8 100644
--- a/lld/test/ELF/gnustack.s
+++ b/lld/test/ELF/gnustack.s
@@ -1,17 +1,20 @@
 # REQUIRES: x86
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64 x.s -o x.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64 nox.s -o nox.o
 
-# RUN: ld.lld %t1 -z execstack -o %t
-# RUN: llvm-readobj --program-headers -S %t | FileCheck --check-prefix=RWX %s
+# RUN: ld.lld a.o -z execstack -o out
+# RUN: llvm-readobj --program-headers -S out | FileCheck --check-prefix=RWX %s
 
-# RUN: ld.lld %t1 -o %t
-# RUN: llvm-readobj --program-headers -S %t | FileCheck --check-prefix=RW %s
+# RUN: ld.lld a.o -o out
+# RUN: llvm-readobj --program-headers -S out | FileCheck --check-prefix=RW %s
 
-# RUN: ld.lld %t1 -o %t -z noexecstack
-# RUN: llvm-readobj --program-headers -S %t | FileCheck --check-prefix=RW %s
+# RUN: ld.lld a.o -o out -z noexecstack
+# RUN: llvm-readobj --program-headers -S out | FileCheck --check-prefix=RW %s
 
-# RUN: ld.lld %t1 -o %t -z nognustack
-# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=NOGNUSTACK %s
+# RUN: ld.lld a.o -o out -z nognustack
+# RUN: llvm-readobj --program-headers -s out | FileCheck --check-prefix=NOGNUSTACK %s
 
 # RW:      Type: PT_GNU_STACK
 # RW-NEXT: Offset: 0x0
@@ -40,5 +43,19 @@
 
 # NOGNUSTACK-NOT: Type: PT_GNU_STACK
 
+# RUN: not ld.lld a.o x.o nox.o x.o 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
+# RUN: not ld.lld a.o x.o nox.o x.o -z nognustack 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
+# ERR-COUNT-2: error: x.o: requires an executable stack, but -z execstack is not specified
+
+# RUN: ld.lld a.o x.o nox.o x.o -z execstack --fatal-warnings
+# RUN: ld.lld -r x.o --fatal-warnings
+
+#--- a.s
 .globl _start
 _start:
+
+#--- x.s
+.section .note.GNU-stack,"x"
+
+#--- nox.s
+.section .note.GNU-stack,""

@MaskRay MaskRay requested review from emaste and smithp35 January 23, 2025 05:28
Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. One small suggestion to update the comment.

@@ -1026,8 +1026,15 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// explicitly told to do otherwise (by -z execstack). Because the stack
// executable-ness is controlled solely by command line options,
// .note.GNU-stack sections are simply ignored.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could update the comment. Something like

.note.GNU-stack sections are with one exception, ignored. We give an error message if we encounter an executable .note.GNU-stack to force the user to explicitly request an executable stack.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. Adopted.

.
Created using spr 1.3.5-bogner
@MaskRay MaskRay changed the title [ELF] Error for executable .note.GNU-stack unless -z execstack [ELF] Error for executable .note.GNU-stack unless -z execstack or -r Jan 23, 2025
@MaskRay MaskRay merged commit e00f1f8 into main Jan 23, 2025
5 of 6 checks passed
@MaskRay MaskRay deleted the users/MaskRay/spr/elf-error-for-executable-notegnu-stack-unless-z-execstack branch January 23, 2025 17:32
github-actions bot pushed a commit to arm/arm-toolchain that referenced this pull request Jan 23, 2025
…tack or -r

.note.GNU-stack with the SHF_EXECINSTR flag requires an executable
stack. This is exceedingly rare. We report an error to force
the user to explicitly request an executable stack.

Close #121234

Pull Request: llvm/llvm-project#124068
@vitalybuka
Copy link
Collaborator

thurstond added a commit to llvm/llvm-zorg that referenced this pull request Jan 24, 2025
@thurstond
Copy link
Contributor

https://lab.llvm.org/buildbot/#/builders/139/builds/9570

CC @thurstond

Thanks @vitalybuka! I've updated the QEMU buildbot to add -z execstack for MIPS scudo builds (llvm/llvm-zorg@3860e16)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

lld silently ignores .note.GNU-stack section that requests exectuable stack
5 participants