patches/binutils/2.20/150-pt-pax-flags-20090909.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Jan 12 19:24:03 2010 +0100 (2010-01-12)
changeset 1761 88020b2c3246
permissions -rw-r--r--
scripts/functions: change handling of nochdir

- 'nochdir' must be the first option
- have systematic pushd/popd, even if nochdir
yann@1614
     1
--- binutils-2.20/bfd/elf-bfd.h
yann@1614
     2
+++ binutils-2.20/bfd/elf-bfd.h
yann@1614
     3
@@ -1527,6 +1527,9 @@ struct elf_obj_tdata
yann@1614
     4
   /* Segment flags for the PT_GNU_STACK segment.  */
yann@1614
     5
   unsigned int stack_flags;
yann@1614
     6
 
yann@1614
     7
+  /* Segment flags for the PT_PAX_FLAGS segment.  */
yann@1614
     8
+  unsigned int pax_flags;
yann@1614
     9
+
yann@1614
    10
   /* Symbol version definitions in external objects.  */
yann@1614
    11
   Elf_Internal_Verdef *verdef;
yann@1614
    12
 
yann@1614
    13
--- binutils-2.20/bfd/elf.c
yann@1614
    14
+++ binutils-2.20/bfd/elf.c
yann@1614
    15
@@ -1081,6 +1081,7 @@ get_segment_type (unsigned int p_type)
yann@1614
    16
     case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
yann@1614
    17
     case PT_GNU_STACK: pt = "STACK"; break;
yann@1614
    18
     case PT_GNU_RELRO: pt = "RELRO"; break;
yann@1614
    19
+    case PT_PAX_FLAGS: pt = "PAX_FLAGS"; break;
yann@1614
    20
     default: pt = NULL; break;
yann@1614
    21
     }
yann@1614
    22
   return pt;
yann@1614
    23
@@ -2379,6 +2380,9 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index)
yann@1614
    24
     case PT_GNU_RELRO:
yann@1614
    25
       return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro");
yann@1614
    26
 
yann@1614
    27
+    case PT_PAX_FLAGS:
yann@1614
    28
+      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "pax_flags");
yann@1614
    29
+
yann@1614
    30
     default:
yann@1614
    31
       /* Check for any processor-specific program segment types.  */
yann@1614
    32
       bed = get_elf_backend_data (abfd);
yann@1614
    33
@@ -3393,6 +3397,11 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
yann@1614
    34
       ++segs;
yann@1614
    35
     }
yann@1614
    36
 
yann@1614
    37
+    {
yann@1614
    38
+      /* We need a PT_PAX_FLAGS segment.  */
yann@1614
    39
+      ++segs;
yann@1614
    40
+    }
yann@1614
    41
+
yann@1614
    42
   for (s = abfd->sections; s != NULL; s = s->next)
yann@1614
    43
     {
yann@1614
    44
       if ((s->flags & SEC_LOAD) != 0
yann@1614
    45
@@ -3972,6 +3981,20 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
yann@1614
    46
 	    }
yann@1614
    47
 	}
yann@1614
    48
 
yann@1614
    49
+    {
yann@1614
    50
+      amt = sizeof (struct elf_segment_map);
yann@1614
    51
+      m = bfd_zalloc (abfd, amt);
yann@1614
    52
+      if (m == NULL)
yann@1614
    53
+	goto error_return;
yann@1614
    54
+      m->next = NULL;
yann@1614
    55
+      m->p_type = PT_PAX_FLAGS;
yann@1614
    56
+      m->p_flags = elf_tdata (abfd)->pax_flags;
yann@1614
    57
+      m->p_flags_valid = 1;
yann@1614
    58
+
yann@1614
    59
+      *pm = m;
yann@1614
    60
+      pm = &m->next;
yann@1614
    61
+    }
yann@1614
    62
+
yann@1614
    63
       free (sections);
yann@1614
    64
       elf_tdata (abfd)->segment_map = mfirst;
yann@1614
    65
     }
yann@1614
    66
@@ -5176,7 +5199,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
yann@1614
    67
        6. PT_TLS segment includes only SHF_TLS sections.
yann@1614
    68
        7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
yann@1614
    69
        8. PT_DYNAMIC should not contain empty sections at the beginning
yann@1614
    70
-	  (with the possible exception of .dynamic).  */
yann@1614
    71
+	  (with the possible exception of .dynamic).
yann@1614
    72
+       9. PT_PAX_FLAGS segments do not include any sections.  */
yann@1614
    73
 #define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed)		\
yann@1614
    74
   ((((segment->p_paddr							\
yann@1614
    75
       ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)	\
yann@1614
    76
@@ -5184,6 +5208,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
yann@1614
    77
      && (section->flags & SEC_ALLOC) != 0)				\
yann@1614
    78
     || IS_NOTE (segment, section))					\
yann@1614
    79
    && segment->p_type != PT_GNU_STACK					\
yann@1614
    80
+   && segment->p_type != PT_PAX_FLAGS					\
yann@1614
    81
    && (segment->p_type != PT_TLS					\
yann@1614
    82
        || (section->flags & SEC_THREAD_LOCAL))				\
yann@1614
    83
    && (segment->p_type == PT_LOAD					\
yann@1614
    84
--- binutils-2.20/bfd/elflink.c
yann@1614
    85
+++ binutils-2.20/bfd/elflink.c
yann@1614
    86
@@ -5465,16 +5465,30 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
yann@1614
    87
     return TRUE;
yann@1614
    88
 
yann@1614
    89
   bed = get_elf_backend_data (output_bfd);
yann@1614
    90
+
yann@1614
    91
+  elf_tdata (output_bfd)->pax_flags = PF_NORANDEXEC;
yann@1614
    92
+  if (info->execheap)
yann@1614
    93
+    elf_tdata (output_bfd)->pax_flags |= PF_NOMPROTECT;
yann@1614
    94
+  else if (info->noexecheap)
yann@1614
    95
+    elf_tdata (output_bfd)->pax_flags |= PF_MPROTECT;
yann@1614
    96
+
yann@1614
    97
   if (info->execstack)
yann@1614
    98
-    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
yann@1614
    99
+    {
yann@1614
   100
+      elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
yann@1614
   101
+      elf_tdata (output_bfd)->pax_flags |= PF_EMUTRAMP;
yann@1614
   102
+    }
yann@1614
   103
   else if (info->noexecstack)
yann@1614
   104
-    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
yann@1614
   105
+    {
yann@1614
   106
+      elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
yann@1614
   107
+      elf_tdata (output_bfd)->pax_flags |= PF_NOEMUTRAMP;
yann@1614
   108
+    }
yann@1614
   109
   else
yann@1614
   110
     {
yann@1614
   111
       bfd *inputobj;
yann@1614
   112
       asection *notesec = NULL;
yann@1614
   113
       int exec = 0;
yann@1614
   114
 
yann@1614
   115
+      elf_tdata (output_bfd)->pax_flags |= PF_NOEMUTRAMP;
yann@1614
   116
       for (inputobj = info->input_bfds;
yann@1614
   117
 	   inputobj;
yann@1614
   118
 	   inputobj = inputobj->link_next)
yann@1614
   119
@@ -5487,7 +5501,11 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
yann@1614
   120
 	  if (s)
yann@1614
   121
 	    {
yann@1614
   122
 	      if (s->flags & SEC_CODE)
yann@1614
   123
-		exec = PF_X;
yann@1614
   124
+		{
yann@1614
   125
+		  elf_tdata (output_bfd)->pax_flags &= ~PF_NOEMUTRAMP;
yann@1614
   126
+		  elf_tdata (output_bfd)->pax_flags |= PF_EMUTRAMP;
yann@1614
   127
+		  exec = PF_X;
yann@1614
   128
+		}
yann@1614
   129
 	      notesec = s;
yann@1614
   130
 	    }
yann@1614
   131
 	  else if (bed->default_execstack)
yann@1614
   132
--- binutils-2.20/binutils/readelf.c
yann@1614
   133
+++ binutils-2.20/binutils/readelf.c
yann@1614
   134
@@ -2556,6 +2556,7 @@ get_segment_type (unsigned long p_type)
yann@1614
   135
 			return "GNU_EH_FRAME";
yann@1614
   136
     case PT_GNU_STACK:	return "GNU_STACK";
yann@1614
   137
     case PT_GNU_RELRO:  return "GNU_RELRO";
yann@1614
   138
+    case PT_PAX_FLAGS:  return "PAX_FLAGS";
yann@1614
   139
 
yann@1614
   140
     default:
yann@1614
   141
       if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
yann@1614
   142
--- binutils-2.20/include/bfdlink.h
yann@1614
   143
+++ binutils-2.20/include/bfdlink.h
yann@1614
   144
@@ -319,6 +319,14 @@ struct bfd_link_info
yann@1614
   145
   /* TRUE if PT_GNU_RELRO segment should be created.  */
yann@1614
   146
   unsigned int relro: 1;
yann@1614
   147
 
yann@1614
   148
+  /* TRUE if PT_PAX_FLAGS segment should be created with PF_NOMPROTECT
yann@1614
   149
+     flags.  */
yann@1614
   150
+  unsigned int execheap: 1;
yann@1614
   151
+
yann@1614
   152
+  /* TRUE if PT_PAX_FLAGS segment should be created with PF_MPROTECT
yann@1614
   153
+     flags.  */
yann@1614
   154
+  unsigned int noexecheap: 1;
yann@1614
   155
+
yann@1614
   156
   /* TRUE if we should warn when adding a DT_TEXTREL to a shared object.  */
yann@1614
   157
   unsigned int warn_shared_textrel: 1;
yann@1614
   158
 
yann@1614
   159
--- binutils-2.20/include/elf/common.h
yann@1614
   160
+++ binutils-2.20/include/elf/common.h
yann@1614
   161
@@ -422,6 +422,7 @@
yann@1614
   162
 #define PT_SUNW_EH_FRAME PT_GNU_EH_FRAME      /* Solaris uses the same value */
yann@1614
   163
 #define PT_GNU_STACK	(PT_LOOS + 0x474e551) /* Stack flags */
yann@1614
   164
 #define PT_GNU_RELRO	(PT_LOOS + 0x474e552) /* Read-only after relocation */
yann@1614
   165
+#define PT_PAX_FLAGS	(PT_LOOS + 0x5041580) /* PaX flags */
yann@1614
   166
 
yann@1614
   167
 /* Program segment permissions, in program header p_flags field.  */
yann@1614
   168
 
yann@1614
   169
@@ -432,6 +433,21 @@
yann@1614
   170
 #define PF_MASKOS	0x0FF00000	/* New value, Oct 4, 1999 Draft */
yann@1614
   171
 #define PF_MASKPROC	0xF0000000	/* Processor-specific reserved bits */
yann@1614
   172
 
yann@1614
   173
+/* Flags to control PaX behavior.  */
yann@1614
   174
+
yann@1614
   175
+#define PF_PAGEEXEC	(1 << 4)	/* Enable  PAGEEXEC */
yann@1614
   176
+#define PF_NOPAGEEXEC	(1 << 5)	/* Disable PAGEEXEC */
yann@1614
   177
+#define PF_SEGMEXEC	(1 << 6)	/* Enable  SEGMEXEC */
yann@1614
   178
+#define PF_NOSEGMEXEC	(1 << 7)	/* Disable SEGMEXEC */
yann@1614
   179
+#define PF_MPROTECT	(1 << 8)	/* Enable  MPROTECT */
yann@1614
   180
+#define PF_NOMPROTECT	(1 << 9)	/* Disable MPROTECT */
yann@1614
   181
+#define PF_RANDEXEC	(1 << 10)	/* Enable  RANDEXEC */
yann@1614
   182
+#define PF_NORANDEXEC	(1 << 11)	/* Disable RANDEXEC */
yann@1614
   183
+#define PF_EMUTRAMP	(1 << 12)	/* Enable  EMUTRAMP */
yann@1614
   184
+#define PF_NOEMUTRAMP	(1 << 13)	/* Disable EMUTRAMP */
yann@1614
   185
+#define PF_RANDMMAP	(1 << 14)	/* Enable  RANDMMAP */
yann@1614
   186
+#define PF_NORANDMMAP	(1 << 15)	/* Disable RANDMMAP */
yann@1614
   187
+
yann@1614
   188
 /* Values for section header, sh_type field.  */
yann@1614
   189
 
yann@1614
   190
 #define SHT_NULL	0		/* Section header table entry unused */
yann@1614
   191
--- binutils-2.20/ld/emultempl/elf32.em
yann@1614
   192
+++ binutils-2.20/ld/emultempl/elf32.em
yann@1614
   193
@@ -2159,6 +2159,16 @@ fragment <<EOF
yann@1614
   194
 	  link_info.noexecstack = TRUE;
yann@1614
   195
 	  link_info.execstack = FALSE;
yann@1614
   196
 	}
yann@1614
   197
+      else if (strcmp (optarg, "execheap") == 0)
yann@1614
   198
+	{
yann@1614
   199
+	  link_info.execheap = TRUE;
yann@1614
   200
+	  link_info.noexecheap = FALSE;
yann@1614
   201
+	}
yann@1614
   202
+      else if (strcmp (optarg, "noexecheap") == 0)
yann@1614
   203
+	{
yann@1614
   204
+	  link_info.noexecheap = TRUE;
yann@1614
   205
+	  link_info.execheap = FALSE;
yann@1614
   206
+	}
yann@1614
   207
 EOF
yann@1614
   208
 
yann@1614
   209
   if test -n "$COMMONPAGESIZE"; then
yann@1614
   210
@@ -2237,6 +2247,8 @@ fragment <<EOF
yann@1614
   211
   fprintf (file, _("\
yann@1614
   212
   -z execstack                Mark executable as requiring executable stack\n"));
yann@1614
   213
   fprintf (file, _("\
yann@1614
   214
+  -z execheap                 Mark executable as requiring executable heap\n"));
yann@1614
   215
+  fprintf (file, _("\
yann@1614
   216
   -z initfirst                Mark DSO to be initialized first at runtime\n"));
yann@1614
   217
   fprintf (file, _("\
yann@1614
   218
   -z interpose                Mark object to interpose all DSOs but executable\n"));
yann@1614
   219
@@ -2260,6 +2272,8 @@ fragment <<EOF
yann@1614
   220
   -z nodump                   Mark DSO not available to dldump\n"));
yann@1614
   221
   fprintf (file, _("\
yann@1614
   222
   -z noexecstack              Mark executable as not requiring executable stack\n"));
yann@1614
   223
+  fprintf (file, _("\
yann@1614
   224
+  -z noexecheap               Mark executable as not requiring executable heap\n"));
yann@1614
   225
 EOF
yann@1614
   226
 
yann@1614
   227
   if test -n "$COMMONPAGESIZE"; then
yann@1614
   228
--- binutils-2.20/ld/ldgram.y
yann@1614
   229
+++ binutils-2.20/ld/ldgram.y
yann@1614
   230
@@ -1116,6 +1116,8 @@ phdr_type:
yann@1614
   231
 			    $$ = exp_intop (0x6474e550);
yann@1614
   232
 			  else if (strcmp (s, "PT_GNU_STACK") == 0)
yann@1614
   233
 			    $$ = exp_intop (0x6474e551);
yann@1614
   234
+			  else if (strcmp (s, "PT_PAX_FLAGS") == 0)
yann@1614
   235
+			    $$ = exp_intop (0x65041580);
yann@1614
   236
 			  else
yann@1614
   237
 			    {
yann@1614
   238
 			      einfo (_("\