1 /* Operating system support for run-time dynamic linker.  Generic Unix version.
2    Copyright (C) 1995-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 /* We conditionalize the whole of this file rather than simply eliding it
20    from the static build, because other sysdeps/ versions of this file
21    might define things needed by a static build.  */
22 
23 #ifdef SHARED
24 
25 #include <assert.h>
26 #include <elf.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <libintl.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/mman.h>
36 #include <ldsodefs.h>
37 #include <_itoa.h>
38 #include <fpu_control.h>
39 
40 #include <entry.h>
41 #include <dl-machine.h>
42 #include <dl-procinfo.h>
43 #include <dl-osinfo.h>
44 #include <libc-internal.h>
45 #include <tls.h>
46 
47 #include <dl-tunables.h>
48 #include <dl-auxv.h>
49 #include <dl-hwcap-check.h>
50 
51 extern char **_environ attribute_hidden;
52 extern char _end[] attribute_hidden;
53 
54 /* Protect SUID program against misuse of file descriptors.  */
55 extern void __libc_check_standard_fds (void);
56 
57 int __libc_enable_secure attribute_relro = 0;
58 rtld_hidden_data_def (__libc_enable_secure)
59 /* This variable contains the lowest stack address ever used.  */
60 void *__libc_stack_end attribute_relro = NULL;
61 rtld_hidden_data_def(__libc_stack_end)
62 void *_dl_random attribute_relro = NULL;
63 
64 #ifndef DL_FIND_ARG_COMPONENTS
65 # define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp)	\
66   do {									      \
67     void **_tmp;							      \
68     (argc) = *(long int *) cookie;					      \
69     (argv) = (char **) ((long int *) cookie + 1);			      \
70     (envp) = (argv) + (argc) + 1;					      \
71     for (_tmp = (void **) (envp); *_tmp; ++_tmp)			      \
72       continue;								      \
73     (auxp) = (void *) ++_tmp;						      \
74   } while (0)
75 #endif
76 
77 #ifndef DL_STACK_END
78 # define DL_STACK_END(cookie) ((void *) (cookie))
79 #endif
80 
81 ElfW(Addr)
_dl_sysdep_start(void ** start_argptr,void (* dl_main)(const ElfW (Phdr)* phdr,ElfW (Word)phnum,ElfW (Addr)* user_entry,ElfW (auxv_t)* auxv))82 _dl_sysdep_start (void **start_argptr,
83 		  void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
84 				   ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
85 {
86   const ElfW(Phdr) *phdr = NULL;
87   ElfW(Word) phnum = 0;
88   ElfW(Addr) user_entry;
89   ElfW(auxv_t) *av;
90 #ifdef HAVE_AUX_SECURE
91 # define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
92 # define set_seen_secure() ((void) 0)
93 #else
94   uid_t uid = 0;
95   gid_t gid = 0;
96   unsigned int seen = 0;
97 # define set_seen_secure() (seen = -1)
98 # ifdef HAVE_AUX_XID
99 #  define set_seen(tag) (tag)	/* Evaluate for the side effects.  */
100 # else
101 #  define M(type) (1 << (type))
102 #  define set_seen(tag) seen |= M ((tag)->a_type)
103 # endif
104 #endif
105 #ifdef NEED_DL_SYSINFO
106   uintptr_t new_sysinfo = 0;
107 #endif
108 
109   __libc_stack_end = DL_STACK_END (start_argptr);
110   DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, _dl_argv, _environ,
111 			  GLRO(dl_auxv));
112 
113   user_entry = (ElfW(Addr)) ENTRY_POINT;
114   GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
115 
116   /* NB: Default to a constant CONSTANT_MINSIGSTKSZ.  */
117   _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
118 		  "CONSTANT_MINSIGSTKSZ is constant");
119   GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
120 
121   for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
122     switch (av->a_type)
123       {
124       case AT_PHDR:
125 	phdr = (void *) av->a_un.a_val;
126 	break;
127       case AT_PHNUM:
128 	phnum = av->a_un.a_val;
129 	break;
130       case AT_PAGESZ:
131 	GLRO(dl_pagesize) = av->a_un.a_val;
132 	break;
133       case AT_ENTRY:
134 	user_entry = av->a_un.a_val;
135 	break;
136 #ifndef HAVE_AUX_SECURE
137       case AT_UID:
138       case AT_EUID:
139 	uid ^= av->a_un.a_val;
140 	break;
141       case AT_GID:
142       case AT_EGID:
143 	gid ^= av->a_un.a_val;
144 	break;
145 #endif
146       case AT_SECURE:
147 #ifndef HAVE_AUX_SECURE
148 	seen = -1;
149 #endif
150 	__libc_enable_secure = av->a_un.a_val;
151 	break;
152       case AT_PLATFORM:
153 	GLRO(dl_platform) = (void *) av->a_un.a_val;
154 	break;
155       case AT_HWCAP:
156 	GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
157 	break;
158       case AT_HWCAP2:
159 	GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
160 	break;
161       case AT_CLKTCK:
162 	GLRO(dl_clktck) = av->a_un.a_val;
163 	break;
164       case AT_FPUCW:
165 	GLRO(dl_fpu_control) = av->a_un.a_val;
166 	break;
167 #ifdef NEED_DL_SYSINFO
168       case AT_SYSINFO:
169 	new_sysinfo = av->a_un.a_val;
170 	break;
171 #endif
172 #ifdef NEED_DL_SYSINFO_DSO
173       case AT_SYSINFO_EHDR:
174 	GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
175 	break;
176 #endif
177       case AT_RANDOM:
178 	_dl_random = (void *) av->a_un.a_val;
179 	break;
180       case AT_MINSIGSTKSZ:
181 	GLRO(dl_minsigstacksize) = av->a_un.a_val;
182 	break;
183       DL_PLATFORM_AUXV
184       }
185 
186   dl_hwcap_check ();
187 
188 #ifndef HAVE_AUX_SECURE
189   if (seen != -1)
190     {
191       /* Fill in the values we have not gotten from the kernel through the
192 	 auxiliary vector.  */
193 # ifndef HAVE_AUX_XID
194 #  define SEE(UID, var, uid) \
195    if ((seen & M (AT_##UID)) == 0) var ^= __get##uid ()
196       SEE (UID, uid, uid);
197       SEE (EUID, uid, euid);
198       SEE (GID, gid, gid);
199       SEE (EGID, gid, egid);
200 # endif
201 
202       /* If one of the two pairs of IDs does not match this is a setuid
203 	 or setgid run.  */
204       __libc_enable_secure = uid | gid;
205     }
206 #endif
207 
208 #ifndef HAVE_AUX_PAGESIZE
209   if (GLRO(dl_pagesize) == 0)
210     GLRO(dl_pagesize) = __getpagesize ();
211 #endif
212 
213 #ifdef NEED_DL_SYSINFO
214   if (new_sysinfo != 0)
215     {
216 # ifdef NEED_DL_SYSINFO_DSO
217       /* Only set the sysinfo value if we also have the vsyscall DSO.  */
218       if (GLRO(dl_sysinfo_dso) != 0)
219 # endif
220         GLRO(dl_sysinfo) = new_sysinfo;
221     }
222 #endif
223 
224   __tunables_init (_environ);
225 
226   /* Initialize DSO sorting algorithm after tunables.  */
227   _dl_sort_maps_init ();
228 
229 #ifdef DL_SYSDEP_INIT
230   DL_SYSDEP_INIT;
231 #endif
232 
233 #ifdef DL_PLATFORM_INIT
234   DL_PLATFORM_INIT;
235 #endif
236 
237   /* Determine the length of the platform name.  */
238   if (GLRO(dl_platform) != NULL)
239     GLRO(dl_platformlen) = strlen (GLRO(dl_platform));
240 
241   if (__sbrk (0) == _end)
242     /* The dynamic linker was run as a program, and so the initial break
243        starts just after our bss, at &_end.  The malloc in dl-minimal.c
244        will consume the rest of this page, so tell the kernel to move the
245        break up that far.  When the user program examines its break, it
246        will see this new value and not clobber our data.  */
247     __sbrk (GLRO(dl_pagesize)
248 	    - ((_end - (char *) 0) & (GLRO(dl_pagesize) - 1)));
249 
250   /* If this is a SUID program we make sure that FDs 0, 1, and 2 are
251      allocated.  If necessary we are doing it ourself.  If it is not
252      possible we stop the program.  */
253   if (__builtin_expect (__libc_enable_secure, 0))
254     __libc_check_standard_fds ();
255 
256   (*dl_main) (phdr, phnum, &user_entry, GLRO(dl_auxv));
257   return user_entry;
258 }
259 
260 void
_dl_sysdep_start_cleanup(void)261 _dl_sysdep_start_cleanup (void)
262 {
263 }
264 
265 void
_dl_show_auxv(void)266 _dl_show_auxv (void)
267 {
268   char buf[64];
269   ElfW(auxv_t) *av;
270 
271   /* Terminate string.  */
272   buf[63] = '\0';
273 
274   /* The following code assumes that the AT_* values are encoded
275      starting from 0 with AT_NULL, 1 for AT_IGNORE, and all other values
276      close by (otherwise the array will be too large).  In case we have
277      to support a platform where these requirements are not fulfilled
278      some alternative implementation has to be used.  */
279   for (av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av)
280     {
281       static const struct
282       {
283 	const char label[22];
284 	enum { unknown = 0, dec, hex, str, ignore } form : 8;
285       } auxvars[] =
286 	{
287 	  [AT_EXECFD - 2] =		{ "EXECFD:            ", dec },
288 	  [AT_EXECFN - 2] =		{ "EXECFN:            ", str },
289 	  [AT_PHDR - 2] =		{ "PHDR:              0x", hex },
290 	  [AT_PHENT - 2] =		{ "PHENT:             ", dec },
291 	  [AT_PHNUM - 2] =		{ "PHNUM:             ", dec },
292 	  [AT_PAGESZ - 2] =		{ "PAGESZ:            ", dec },
293 	  [AT_BASE - 2] =		{ "BASE:              0x", hex },
294 	  [AT_FLAGS - 2] =		{ "FLAGS:             0x", hex },
295 	  [AT_ENTRY - 2] =		{ "ENTRY:             0x", hex },
296 	  [AT_NOTELF - 2] =		{ "NOTELF:            ", hex },
297 	  [AT_UID - 2] =		{ "UID:               ", dec },
298 	  [AT_EUID - 2] =		{ "EUID:              ", dec },
299 	  [AT_GID - 2] =		{ "GID:               ", dec },
300 	  [AT_EGID - 2] =		{ "EGID:              ", dec },
301 	  [AT_PLATFORM - 2] =		{ "PLATFORM:          ", str },
302 	  [AT_HWCAP - 2] =		{ "HWCAP:             ", hex },
303 	  [AT_CLKTCK - 2] =		{ "CLKTCK:            ", dec },
304 	  [AT_FPUCW - 2] =		{ "FPUCW:             ", hex },
305 	  [AT_DCACHEBSIZE - 2] =	{ "DCACHEBSIZE:       0x", hex },
306 	  [AT_ICACHEBSIZE - 2] =	{ "ICACHEBSIZE:       0x", hex },
307 	  [AT_UCACHEBSIZE - 2] =	{ "UCACHEBSIZE:       0x", hex },
308 	  [AT_IGNOREPPC - 2] =		{ "IGNOREPPC", ignore },
309 	  [AT_SECURE - 2] =		{ "SECURE:            ", dec },
310 	  [AT_BASE_PLATFORM - 2] =	{ "BASE_PLATFORM:     ", str },
311 	  [AT_SYSINFO - 2] =		{ "SYSINFO:           0x", hex },
312 	  [AT_SYSINFO_EHDR - 2] =	{ "SYSINFO_EHDR:      0x", hex },
313 	  [AT_RANDOM - 2] =		{ "RANDOM:            0x", hex },
314 	  [AT_HWCAP2 - 2] =		{ "HWCAP2:            0x", hex },
315 	  [AT_MINSIGSTKSZ - 2] =	{ "MINSIGSTKSZ:       ", dec },
316 	  [AT_L1I_CACHESIZE - 2] =	{ "L1I_CACHESIZE:     ", dec },
317 	  [AT_L1I_CACHEGEOMETRY - 2] =	{ "L1I_CACHEGEOMETRY: 0x", hex },
318 	  [AT_L1D_CACHESIZE - 2] =	{ "L1D_CACHESIZE:     ", dec },
319 	  [AT_L1D_CACHEGEOMETRY - 2] =	{ "L1D_CACHEGEOMETRY: 0x", hex },
320 	  [AT_L2_CACHESIZE - 2] =	{ "L2_CACHESIZE:      ", dec },
321 	  [AT_L2_CACHEGEOMETRY - 2] =	{ "L2_CACHEGEOMETRY:  0x", hex },
322 	  [AT_L3_CACHESIZE - 2] =	{ "L3_CACHESIZE:      ", dec },
323 	  [AT_L3_CACHEGEOMETRY - 2] =	{ "L3_CACHEGEOMETRY:  0x", hex },
324 	};
325       unsigned int idx = (unsigned int) (av->a_type - 2);
326 
327       if ((unsigned int) av->a_type < 2u
328 	  || (idx < sizeof (auxvars) / sizeof (auxvars[0])
329 	      && auxvars[idx].form == ignore))
330 	continue;
331 
332       assert (AT_NULL == 0);
333       assert (AT_IGNORE == 1);
334 
335       /* Some entries are handled in a special way per platform.  */
336       if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
337 	continue;
338 
339       if (idx < sizeof (auxvars) / sizeof (auxvars[0])
340 	  && auxvars[idx].form != unknown)
341 	{
342 	  const char *val = (char *) av->a_un.a_val;
343 
344 	  if (__builtin_expect (auxvars[idx].form, dec) == dec)
345 	    val = _itoa ((unsigned long int) av->a_un.a_val,
346 			 buf + sizeof buf - 1, 10, 0);
347 	  else if (__builtin_expect (auxvars[idx].form, hex) == hex)
348 	    val = _itoa ((unsigned long int) av->a_un.a_val,
349 			 buf + sizeof buf - 1, 16, 0);
350 
351 	  _dl_printf ("AT_%s%s\n", auxvars[idx].label, val);
352 
353 	  continue;
354 	}
355 
356       /* Unknown value: print a generic line.  */
357       char buf2[17];
358       buf2[sizeof (buf2) - 1] = '\0';
359       const char *val2 = _itoa ((unsigned long int) av->a_un.a_val,
360 				buf2 + sizeof buf2 - 1, 16, 0);
361       const char *val =  _itoa ((unsigned long int) av->a_type,
362 				buf + sizeof buf - 1, 16, 0);
363       _dl_printf ("AT_??? (0x%s): 0x%s\n", val, val2);
364     }
365 }
366 
367 #endif
368