summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/glibc/965cb60.patch
blob: f8e461b0cba5253471cdb94c5a32825e508428f3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
From 965cb60a21674edb8e20b1a2a41297bcd4622361 Mon Sep 17 00:00:00 2001
From: Ulrich Drepper <drepper@redhat.com>
Date: Sun, 11 Jan 2009 04:44:06 +0000
Subject: [PATCH] * sysdeps/generic/dl-osinfo.h (_dl_setup_stack_chk_guard)

diff --git a/elf/dl-support.c b/elf/dl-support.c
index 6bd573ec57..7b3ccf3d4d 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -84,6 +84,9 @@ struct r_scope_elem _dl_initial_searchlist;
 int _dl_starting_up = 1;
 #endif
 
+/* Random data provided by the kernel.  */
+void *_dl_random;
+
 /* Get architecture specific initializer.  */
 #include <dl-procinfo.c>
 
@@ -216,6 +219,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
 	__libc_enable_secure = av->a_un.a_val;
 	__libc_enable_secure_decided = 1;
 	break;
+      case AT_RANDOM:
+	_dl_random = (void *) av->a_un.a_val;
+	break;
 # ifdef DL_PLATFORM_AUXV
       DL_PLATFORM_AUXV
 # endif
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index e6f4272a63..29ae895473 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -62,6 +62,7 @@ int __libc_multiple_libcs = 0;	/* Defining this here avoids the inclusion
 void *__libc_stack_end attribute_relro = NULL;
 rtld_hidden_data_def(__libc_stack_end)
 static ElfW(auxv_t) *_dl_auxv attribute_relro;
+void *_dl_random attribute_relro = NULL;
 
 #ifndef DL_FIND_ARG_COMPONENTS
 # define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp)	\
@@ -173,6 +174,9 @@ _dl_sysdep_start (void **start_argptr,
 	GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
 	break;
 #endif
+      case AT_RANDOM:
+	_dl_random = (void *) av->a_un.a_val;
+	break;
 #ifdef DL_PLATFORM_AUXV
       DL_PLATFORM_AUXV
 #endif
@@ -294,6 +298,7 @@ _dl_show_auxv (void)
 	  [AT_SECURE - 2] =		{ "AT_SECURE:       ", dec },
 	  [AT_SYSINFO - 2] =		{ "AT_SYSINFO:      0x", hex },
 	  [AT_SYSINFO_EHDR - 2] =	{ "AT_SYSINFO_EHDR: 0x", hex },
+	  [AT_RANDOM - 2] =		{ "AT_RANDOM:       0x", hex },
 	};
       unsigned int idx = (unsigned int) (av->a_type - 2);
 
diff --git a/elf/rtld.c b/elf/rtld.c
index 46bece7fa3..60d414d637 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -841,7 +841,7 @@ static void
 security_init (void)
 {
   /* Set up the stack checker's canary.  */
-  uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
+  uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
 #ifdef THREAD_SET_STACK_GUARD
   THREAD_SET_STACK_GUARD (stack_chk_guard);
 #else
@@ -851,18 +851,18 @@ security_init (void)
   /* Set up the pointer guard as well, if necessary.  */
   if (GLRO(dl_pointer_guard))
     {
-      // XXX If it is cheap, we should use a separate value.
-      uintptr_t pointer_chk_guard = stack_chk_guard;
-#ifndef HP_TIMING_NONAVAIL
-      hp_timing_t now;
-      HP_TIMING_NOW (now);
-      pointer_chk_guard ^= now;
-#endif
+      uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
+							     stack_chk_guard);
 #ifdef THREAD_SET_POINTER_GUARD
       THREAD_SET_POINTER_GUARD (pointer_chk_guard);
 #endif
       __pointer_chk_guard_local = pointer_chk_guard;
     }
+
+  /* We do not need the _dl_random value anymore.  The less
+     information we leave behind, the better, so clear the
+     variable.  */
+  _dl_random = NULL;
 }
 
 
diff --git a/sysdeps/generic/dl-osinfo.h b/sysdeps/generic/dl-osinfo.h
index 60b84a900d..02ec28d424 100644
--- a/sysdeps/generic/dl-osinfo.h
+++ b/sysdeps/generic/dl-osinfo.h
@@ -1,12 +1,29 @@
 #include <stdint.h>
 
 static inline uintptr_t __attribute__ ((always_inline))
-_dl_setup_stack_chk_guard (void)
+_dl_setup_stack_chk_guard (void *dl_random)
 {
-  uintptr_t ret = 0;
-  unsigned char *p = (unsigned char *) &ret;
-  p[sizeof (ret) - 1] = 255;
-  p[sizeof (ret) - 2] = '\n';
-  p[0] = 0;
+  uintptr_t ret;
+  if (dl_random == NULL)
+    {
+      ret = 0;
+      unsigned char *p = (unsigned char *) &ret;
+      p[sizeof (ret) - 1] = 255;
+      p[sizeof (ret) - 2] = '\n';
+      p[0] = 0;
+    }
+  else
+    memcmp (&ret, dl_random, sizeof (ret));
+  return ret;
+}
+
+static inline uintptr_t __attribute__ ((always_inline))
+_dl_setup_pointer_guard (void *dl_random, uintptr_t stack_chk_guard)
+{
+  uintptr_t ret;
+  if (dl_random == NULL)
+    ret = stack_chk_guard;
+  else
+    memcmp (&ret, (char *) dl_random + sizeof (ret), sizeof (ret));
   return ret;
 }
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 4d857404a3..f5606f373f 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -731,6 +731,9 @@ weak_extern (_dl_starting_up)
 extern int _dl_starting_up_internal attribute_hidden;
 #endif
 
+/* Random data provided by the kernel.  */
+extern void *_dl_random attribute_hidden;
+
 /* OS-dependent function to open the zero-fill device.  */
 extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */
 
diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h
index 5271d4e4de..ee8eaf20e4 100644
--- a/sysdeps/unix/sysv/linux/dl-osinfo.h
+++ b/sysdeps/unix/sysv/linux/dl-osinfo.h
@@ -60,22 +60,20 @@ dl_fatal (const char *str)
   } while (0)
 
 static inline uintptr_t __attribute__ ((always_inline))
-_dl_setup_stack_chk_guard (void)
+_dl_setup_stack_chk_guard (void *dl_random)
 {
   uintptr_t ret;
-#ifdef ENABLE_STACKGUARD_RANDOMIZE
-  int fd = __open ("/dev/urandom", O_RDONLY);
-  if (fd >= 0)
-    {
-      ssize_t reslen = __read (fd, &ret, sizeof (ret));
-      __close (fd);
-      if (reslen == (ssize_t) sizeof (ret))
-	return ret;
-    }
-#endif
-  ret = 0;
-  unsigned char *p = (unsigned char *) &ret;
-  p[sizeof (ret) - 1] = 255;
-  p[sizeof (ret) - 2] = '\n';
+    /* We need in the moment only 8 bytes on 32-bit platforms and 16
+       bytes on 64-bit platforms.  Therefore we can use the data
+       directly and not use the kernel-provided data to seed a PRNG.  */
+    memcpy (&ret, dl_random, sizeof (ret));
+  return ret;
+}
+
+static inline uintptr_t __attribute__ ((always_inline))
+_dl_setup_pointer_guard (void *dl_random, uintptr_t stack_chk_guard)
+{
+  uintptr_t ret;
+    memcpy (&ret, (char *) dl_random + sizeof (ret), sizeof (ret));
   return ret;
 }
diff --git a/csu/libc-start.c b/csu/libc-start.c
index a14ed71616a..80b672f88d8 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -140,7 +140,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
   __pthread_initialize_minimal ();
 
   /* Set up the stack checker's canary.  */
-  uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
+  uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
 # ifdef THREAD_SET_STACK_GUARD
   THREAD_SET_STACK_GUARD (stack_chk_guard);
 # else