[PATCH] D44943: Fill the last page of each executable section with 0xcc or equivalent.

Rui Ueyama via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 27 09:56:57 PDT 2018


ruiu created this revision.
ruiu added a reviewer: grimar.
Herald added subscribers: arichardson, emaste.

I think this patch is better than https://reviews.llvm.org/D44775.


https://reviews.llvm.org/D44943

Files:
  lld/ELF/Writer.cpp
  lld/test/ELF/fill-trap.s


Index: lld/test/ELF/fill-trap.s
===================================================================
--- lld/test/ELF/fill-trap.s
+++ lld/test/ELF/fill-trap.s
@@ -3,23 +3,25 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
 # RUN: ld.lld %t -o %t2
 # RUN: llvm-readobj -program-headers %t2 | FileCheck %s
-# RUN: od -Ax -x -N16 -j0x1ff0 %t2 | FileCheck %s -check-prefix=FILL
+# RUN: od -Ax -t x1 -N16 -j0x1000 %t2 | FileCheck %s -check-prefix=FILL
 
-# CHECK: ProgramHeader {
-# CHECK:   Type: PT_LOAD
-# CHECK:   Offset: 0x1000
+# CHECK:      ProgramHeader {
+# CHECK:        Type: PT_LOAD
+# CHECK:        Offset: 0x1000
 # CHECK-NEXT:   VirtualAddress:
 # CHECK-NEXT:   PhysicalAddress:
-# CHECK-NEXT:   FileSize: 4096
+# CHECK-NEXT:   FileSize: 8192
 # CHECK-NEXT:   MemSize:
 # CHECK-NEXT:   Flags [
 # CHECK-NEXT:     PF_R
 # CHECK-NEXT:     PF_X
 # CHECK-NEXT:   ]
 
-## Check that executable page is filled with traps at its end.
-# FILL: 001ff0 cccc cccc cccc cccc cccc cccc cccc cccc
+# FILL: 001000 90 cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc
 
-.globl _start
-_start:
-  nop
+nop
+
+.section .foo,"ax"
+.align 16
+nop
+.zero 0x1000
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -2182,12 +2182,7 @@
       Sec->writeTo<ELFT>(Buf + Sec->Offset);
 }
 
-static void fillTrap(uint8_t *I, uint8_t *End) {
-  for (; I + 4 <= End; I += 4)
-    memcpy(I, &Target->TrapInstr, 4);
-}
-
-// Fill the last page of executable segments with trap instructions
+// Fill the last pages of executable sections with trap instructions
 // instead of leaving them as zero. Even though it is not required by any
 // standard, it is in general a good thing to do for security reasons.
 //
@@ -2197,12 +2192,19 @@
   if (Script->HasSectionsCommand)
     return;
 
-  // Fill the last page.
+  // Fill the last page of each executable section.
   uint8_t *Buf = Buffer->getBufferStart();
-  for (PhdrEntry *P : Phdrs)
-    if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
-      fillTrap(Buf + alignDown(P->p_offset + P->p_filesz, Target->PageSize),
-               Buf + alignTo(P->p_offset + P->p_filesz, Target->PageSize));
+  for (OutputSection *Sec : OutputSections) {
+    PhdrEntry *P = Sec->PtLoad;
+    if (!P || P->p_type != PT_LOAD || !(P->p_flags & PF_X))
+      continue;
+    if ((Sec->Offset + Sec->Size) % Target->PageSize == 0)
+      continue;
+
+    assert(sizeof(Target->TrapInstr) == sizeof(int));
+    memset(Buf + alignDown(Sec->Offset + Sec->Size, Target->PageSize),
+           Target->TrapInstr, Target->PageSize);
+  }
 
   // Round up the file size of the last segment to the page boundary iff it is
   // an executable segment to ensure that other tools don't accidentally


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44943.139949.patch
Type: text/x-patch
Size: 2810 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180327/2fd97568/attachment.bin>


More information about the llvm-commits mailing list