patches/binutils/2.19/140-pt-pax-flags-20081101.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Apr 26 10:47:00 2009 +0000 (2009-04-26)
branch1.4
changeset 1307 39b1c755f19b
permissions -rw-r--r--
1.4: update version to 1.4.0.

-------- diffstat follows --------
/branches/1.4/.version | 2 1 1 0 +-
1 file changed, 1 insertion(+), 1 deletion(-)
yann@1069
     1
Original patch from Gentoo:
yann@1069
     2
gentoo/src/patchsets/binutils/2.19/63_all_binutils-2.19-pt-pax-flags-20081101.patch
yann@1069
     3
yann@1069
     4
diff -durN binutils-2.19.orig/bfd/elf-bfd.h binutils-2.19/bfd/elf-bfd.h
yann@1069
     5
--- binutils-2.19.orig/bfd/elf-bfd.h	2008-08-21 01:28:58.000000000 +0200
yann@1069
     6
+++ binutils-2.19/bfd/elf-bfd.h	2008-11-23 16:31:09.000000000 +0100
yann@1069
     7
@@ -1526,6 +1526,9 @@
yann@1069
     8
   /* Segment flags for the PT_GNU_STACK segment.  */
yann@1069
     9
   unsigned int stack_flags;
yann@1069
    10
 
yann@1069
    11
+  /* Segment flags for the PT_PAX_FLAGS segment.  */
yann@1069
    12
+  unsigned int pax_flags;
yann@1069
    13
+
yann@1069
    14
   /* Symbol version definitions in external objects.  */
yann@1069
    15
   Elf_Internal_Verdef *verdef;
yann@1069
    16
 
yann@1069
    17
diff -durN binutils-2.19.orig/bfd/elf.c binutils-2.19/bfd/elf.c
yann@1069
    18
--- binutils-2.19.orig/bfd/elf.c	2008-10-09 14:18:23.000000000 +0200
yann@1069
    19
+++ binutils-2.19/bfd/elf.c	2008-11-23 16:31:09.000000000 +0100
yann@1069
    20
@@ -1136,6 +1136,7 @@
yann@1069
    21
     case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
yann@1069
    22
     case PT_GNU_STACK: pt = "STACK"; break;
yann@1069
    23
     case PT_GNU_RELRO: pt = "RELRO"; break;
yann@1069
    24
+    case PT_PAX_FLAGS: pt = "PAX_FLAGS"; break;
yann@1069
    25
     default: pt = NULL; break;
yann@1069
    26
     }
yann@1069
    27
   return pt;
yann@1069
    28
@@ -2442,6 +2443,9 @@
yann@1069
    29
     case PT_GNU_RELRO:
yann@1069
    30
       return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro");
yann@1069
    31
 
yann@1069
    32
+    case PT_PAX_FLAGS:
yann@1069
    33
+      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "pax_flags");
yann@1069
    34
+
yann@1069
    35
     default:
yann@1069
    36
       /* Check for any processor-specific program segment types.  */
yann@1069
    37
       bed = get_elf_backend_data (abfd);
yann@1069
    38
@@ -3404,6 +3408,11 @@
yann@1069
    39
       ++segs;
yann@1069
    40
     }
yann@1069
    41
 
yann@1069
    42
+    {
yann@1069
    43
+      /* We need a PT_PAX_FLAGS segment.  */
yann@1069
    44
+      ++segs;
yann@1069
    45
+    }
yann@1069
    46
+
yann@1069
    47
   for (s = abfd->sections; s != NULL; s = s->next)
yann@1069
    48
     {
yann@1069
    49
       if ((s->flags & SEC_LOAD) != 0
yann@1069
    50
@@ -3983,6 +3992,20 @@
yann@1069
    51
 	    }
yann@1069
    52
 	}
yann@1069
    53
 
yann@1069
    54
+    {
yann@1069
    55
+      amt = sizeof (struct elf_segment_map);
yann@1069
    56
+      m = bfd_zalloc (abfd, amt);
yann@1069
    57
+      if (m == NULL)
yann@1069
    58
+	goto error_return;
yann@1069
    59
+      m->next = NULL;
yann@1069
    60
+      m->p_type = PT_PAX_FLAGS;
yann@1069
    61
+      m->p_flags = elf_tdata (abfd)->pax_flags;
yann@1069
    62
+      m->p_flags_valid = 1;
yann@1069
    63
+
yann@1069
    64
+      *pm = m;
yann@1069
    65
+      pm = &m->next;
yann@1069
    66
+    }
yann@1069
    67
+
yann@1069
    68
       free (sections);
yann@1069
    69
       elf_tdata (abfd)->segment_map = mfirst;
yann@1069
    70
     }
yann@1069
    71
@@ -5173,7 +5196,8 @@
yann@1069
    72
        6. PT_TLS segment includes only SHF_TLS sections.
yann@1069
    73
        7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
yann@1069
    74
        8. PT_DYNAMIC should not contain empty sections at the beginning
yann@1069
    75
-	  (with the possible exception of .dynamic).  */
yann@1069
    76
+	  (with the possible exception of .dynamic).
yann@1069
    77
+       9. PT_PAX_FLAGS segments does not include any sections.  */
yann@1069
    78
 #define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed)		\
yann@1069
    79
   ((((segment->p_paddr							\
yann@1069
    80
       ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)	\
yann@1069
    81
@@ -5181,6 +5205,7 @@
yann@1069
    82
      && (section->flags & SEC_ALLOC) != 0)				\
yann@1069
    83
     || IS_NOTE (segment, section))					\
yann@1069
    84
    && segment->p_type != PT_GNU_STACK					\
yann@1069
    85
+   && segment->p_type != PT_PAX_FLAGS					\
yann@1069
    86
    && (segment->p_type != PT_TLS					\
yann@1069
    87
        || (section->flags & SEC_THREAD_LOCAL))				\
yann@1069
    88
    && (segment->p_type == PT_LOAD					\
yann@1069
    89
diff -durN binutils-2.19.orig/bfd/elflink.c binutils-2.19/bfd/elflink.c
yann@1069
    90
--- binutils-2.19.orig/bfd/elflink.c	2008-08-22 10:32:39.000000000 +0200
yann@1069
    91
+++ binutils-2.19/bfd/elflink.c	2008-11-23 16:31:09.000000000 +0100
yann@1069
    92
@@ -5397,16 +5397,30 @@
yann@1069
    93
     return TRUE;
yann@1069
    94
 
yann@1069
    95
   bed = get_elf_backend_data (output_bfd);
yann@1069
    96
+  elf_tdata (output_bfd)->pax_flags = PF_NORANDEXEC;
yann@1069
    97
+
yann@1069
    98
+  if (info->execheap)
yann@1069
    99
+    elf_tdata (output_bfd)->pax_flags |= PF_NOMPROTECT;
yann@1069
   100
+  else if (info->noexecheap)
yann@1069
   101
+    elf_tdata (output_bfd)->pax_flags |= PF_MPROTECT;
yann@1069
   102
+
yann@1069
   103
   if (info->execstack)
yann@1069
   104
-    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
yann@1069
   105
+    {
yann@1069
   106
+      elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
yann@1069
   107
+      elf_tdata (output_bfd)->pax_flags |= PF_EMUTRAMP;
yann@1069
   108
+    }
yann@1069
   109
   else if (info->noexecstack)
yann@1069
   110
-    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
yann@1069
   111
+    {
yann@1069
   112
+      elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
yann@1069
   113
+      elf_tdata (output_bfd)->pax_flags |= PF_NOEMUTRAMP;
yann@1069
   114
+    }
yann@1069
   115
   else
yann@1069
   116
     {
yann@1069
   117
       bfd *inputobj;
yann@1069
   118
       asection *notesec = NULL;
yann@1069
   119
       int exec = 0;
yann@1069
   120
 
yann@1069
   121
+      elf_tdata (output_bfd)->pax_flags |= PF_NOEMUTRAMP;
yann@1069
   122
       for (inputobj = info->input_bfds;
yann@1069
   123
 	   inputobj;
yann@1069
   124
 	   inputobj = inputobj->link_next)
yann@1069
   125
@@ -5419,7 +5433,11 @@
yann@1069
   126
 	  if (s)
yann@1069
   127
 	    {
yann@1069
   128
 	      if (s->flags & SEC_CODE)
yann@1069
   129
-		exec = PF_X;
yann@1069
   130
+		{
yann@1069
   131
+		  elf_tdata (output_bfd)->pax_flags &= ~PF_NOEMUTRAMP;
yann@1069
   132
+		  elf_tdata (output_bfd)->pax_flags |= PF_EMUTRAMP;
yann@1069
   133
+		  exec = PF_X;
yann@1069
   134
+		}
yann@1069
   135
 	      notesec = s;
yann@1069
   136
 	    }
yann@1069
   137
 	  else if (bed->default_execstack)
yann@1069
   138
diff -durN binutils-2.19.orig/binutils/readelf.c binutils-2.19/binutils/readelf.c
yann@1069
   139
--- binutils-2.19.orig/binutils/readelf.c	2008-09-17 11:00:44.000000000 +0200
yann@1069
   140
+++ binutils-2.19/binutils/readelf.c	2008-11-23 16:31:09.000000000 +0100
yann@1069
   141
@@ -2505,6 +2505,7 @@
yann@1069
   142
 			return "GNU_EH_FRAME";
yann@1069
   143
     case PT_GNU_STACK:	return "GNU_STACK";
yann@1069
   144
     case PT_GNU_RELRO:  return "GNU_RELRO";
yann@1069
   145
+    case PT_PAX_FLAGS:  return "PAX_FLAGS";
yann@1069
   146
 
yann@1069
   147
     default:
yann@1069
   148
       if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
yann@1069
   149
diff -durN binutils-2.19.orig/include/bfdlink.h binutils-2.19/include/bfdlink.h
yann@1069
   150
--- binutils-2.19.orig/include/bfdlink.h	2008-08-17 05:12:50.000000000 +0200
yann@1069
   151
+++ binutils-2.19/include/bfdlink.h	2008-11-23 16:31:09.000000000 +0100
yann@1069
   152
@@ -319,6 +319,14 @@
yann@1069
   153
   /* TRUE if PT_GNU_RELRO segment should be created.  */
yann@1069
   154
   unsigned int relro: 1;
yann@1069
   155
 
yann@1069
   156
+  /* TRUE if PT_PAX_FLAGS segment should be created with PF_NOMPROTECT
yann@1069
   157
+     flags.  */
yann@1069
   158
+  unsigned int execheap: 1;
yann@1069
   159
+
yann@1069
   160
+  /* TRUE if PT_PAX_FLAGS segment should be created with PF_MPROTECT
yann@1069
   161
+     flags.  */
yann@1069
   162
+  unsigned int noexecheap: 1;
yann@1069
   163
+
yann@1069
   164
   /* TRUE if we should warn when adding a DT_TEXTREL to a shared object.  */
yann@1069
   165
   unsigned int warn_shared_textrel: 1;
yann@1069
   166
 
yann@1069
   167
diff -durN binutils-2.19.orig/include/elf/common.h binutils-2.19/include/elf/common.h
yann@1069
   168
--- binutils-2.19.orig/include/elf/common.h	2008-08-04 01:20:42.000000000 +0200
yann@1069
   169
+++ binutils-2.19/include/elf/common.h	2008-11-23 16:31:09.000000000 +0100
yann@1069
   170
@@ -360,6 +360,7 @@
yann@1069
   171
 #define PT_SUNW_EH_FRAME PT_GNU_EH_FRAME      /* Solaris uses the same value */
yann@1069
   172
 #define PT_GNU_STACK	(PT_LOOS + 0x474e551) /* Stack flags */
yann@1069
   173
 #define PT_GNU_RELRO	(PT_LOOS + 0x474e552) /* Read-only after relocation */
yann@1069
   174
+#define PT_PAX_FLAGS	(PT_LOOS + 0x5041580) /* PaX flags */
yann@1069
   175
 
yann@1069
   176
 /* Program segment permissions, in program header p_flags field.  */
yann@1069
   177
 
yann@1069
   178
@@ -370,6 +371,21 @@
yann@1069
   179
 #define PF_MASKOS	0x0FF00000	/* New value, Oct 4, 1999 Draft */
yann@1069
   180
 #define PF_MASKPROC	0xF0000000	/* Processor-specific reserved bits */
yann@1069
   181
 
yann@1069
   182
+/* Flags to control PaX behavior.  */
yann@1069
   183
+
yann@1069
   184
+#define PF_PAGEEXEC	(1 << 4)	/* Enable  PAGEEXEC */
yann@1069
   185
+#define PF_NOPAGEEXEC	(1 << 5)	/* Disable PAGEEXEC */
yann@1069
   186
+#define PF_SEGMEXEC	(1 << 6)	/* Enable  SEGMEXEC */
yann@1069
   187
+#define PF_NOSEGMEXEC	(1 << 7)	/* Disable SEGMEXEC */
yann@1069
   188
+#define PF_MPROTECT	(1 << 8)	/* Enable  MPROTECT */
yann@1069
   189
+#define PF_NOMPROTECT	(1 << 9)	/* Disable MPROTECT */
yann@1069
   190
+#define PF_RANDEXEC	(1 << 10)	/* Enable  RANDEXEC */
yann@1069
   191
+#define PF_NORANDEXEC	(1 << 11)	/* Disable RANDEXEC */
yann@1069
   192
+#define PF_EMUTRAMP	(1 << 12)	/* Enable  EMUTRAMP */
yann@1069
   193
+#define PF_NOEMUTRAMP	(1 << 13)	/* Disable EMUTRAMP */
yann@1069
   194
+#define PF_RANDMMAP	(1 << 14)	/* Enable  RANDMMAP */
yann@1069
   195
+#define PF_NORANDMMAP	(1 << 15)	/* Disable RANDMMAP */
yann@1069
   196
+
yann@1069
   197
 /* Values for section header, sh_type field.  */
yann@1069
   198
 
yann@1069
   199
 #define SHT_NULL	0		/* Section header table entry unused */
yann@1069
   200
diff -durN binutils-2.19.orig/ld/emultempl/elf32.em binutils-2.19/ld/emultempl/elf32.em
yann@1069
   201
--- binutils-2.19.orig/ld/emultempl/elf32.em	2008-11-23 16:30:36.000000000 +0100
yann@1069
   202
+++ binutils-2.19/ld/emultempl/elf32.em	2008-11-23 16:31:09.000000000 +0100
yann@1069
   203
@@ -2146,6 +2146,16 @@
yann@1069
   204
 	  link_info.noexecstack = TRUE;
yann@1069
   205
 	  link_info.execstack = FALSE;
yann@1069
   206
 	}
yann@1069
   207
+      else if (strcmp (optarg, "execheap") == 0)
yann@1069
   208
+	{
yann@1069
   209
+	  link_info.execheap = TRUE;
yann@1069
   210
+	  link_info.noexecheap = FALSE;
yann@1069
   211
+	}
yann@1069
   212
+      else if (strcmp (optarg, "noexecheap") == 0)
yann@1069
   213
+	{
yann@1069
   214
+	  link_info.noexecheap = TRUE;
yann@1069
   215
+	  link_info.execheap = FALSE;
yann@1069
   216
+	}
yann@1069
   217
 EOF
yann@1069
   218
 
yann@1069
   219
   if test -n "$COMMONPAGESIZE"; then
yann@1069
   220
@@ -2229,6 +2239,8 @@
yann@1069
   221
   fprintf (file, _("\
yann@1069
   222
   -z execstack                Mark executable as requiring executable stack\n"));
yann@1069
   223
   fprintf (file, _("\
yann@1069
   224
+  -z execheap\t\tMark executable as requiring executable heap\n"));
yann@1069
   225
+  fprintf (file, _("\
yann@1069
   226
   -z initfirst                Mark DSO to be initialized first at runtime\n"));
yann@1069
   227
   fprintf (file, _("\
yann@1069
   228
   -z interpose                Mark object to interpose all DSOs but executable\n"));
yann@1069
   229
@@ -2252,6 +2264,8 @@
yann@1069
   230
   -z nodump                   Mark DSO not available to dldump\n"));
yann@1069
   231
   fprintf (file, _("\
yann@1069
   232
   -z noexecstack              Mark executable as not requiring executable stack\n"));
yann@1069
   233
+  fprintf (file, _("\
yann@1069
   234
+  -z noexecheap\tMark executable as not requiring executable heap\n"));
yann@1069
   235
 EOF
yann@1069
   236
 
yann@1069
   237
   if test -n "$COMMONPAGESIZE"; then
yann@1069
   238
diff -durN binutils-2.19.orig/ld/ldgram.y binutils-2.19/ld/ldgram.y
yann@1069
   239
--- binutils-2.19.orig/ld/ldgram.y	2008-07-06 15:38:36.000000000 +0200
yann@1069
   240
+++ binutils-2.19/ld/ldgram.y	2008-11-23 16:31:09.000000000 +0100
yann@1069
   241
@@ -1112,6 +1112,8 @@
yann@1069
   242
 			    $$ = exp_intop (0x6474e550);
yann@1069
   243
 			  else if (strcmp (s, "PT_GNU_STACK") == 0)
yann@1069
   244
 			    $$ = exp_intop (0x6474e551);
yann@1069
   245
+			  else if (strcmp (s, "PT_PAX_FLAGS") == 0)
yann@1069
   246
+			    $$ = exp_intop (0x65041580);
yann@1069
   247
 			  else
yann@1069
   248
 			    {
yann@1069
   249
 			      einfo (_("\