1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <assert.h>
21: #include <dlfcn.h>
22: #include <errno.h>
23: #include <libintl.h>
24: #include <stdio.h>
25: #include <stdlib.h>
26: #include <string.h>
27: #include <unistd.h>
28: #include <sys/mman.h>
29: #include <sys/param.h>
30: #include <bits/libc-lock.h>
31: #include <ldsodefs.h>
32: #include <bp-sym.h>
33: #include <caller.h>
34: #include <sysdep-cancel.h>
35: #include <tls.h>
36:
37: #include <dl-dst.h>
38:
39:
40: extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
41: void (*dl_main) (const ElfW(Phdr) *phdr,
42: ElfW(Word) phnum,
43: ElfW(Addr) *user_entry));
44: weak_extern (BP_SYM (_dl_sysdep_start))
45:
46: extern int __libc_multiple_libcs;
47:
48:
49:
50: #ifdef SCOPE_DEBUG
51: static void show_scope (struct link_map *new);
52: #endif
53:
54:
55:
56:
57: struct dl_open_args
58: {
59: const char *file;
60: int mode;
61:
62: const void *caller_dlopen;
63:
64: const void *caller_dl_open;
65: struct link_map *map;
66:
67: Lmid_t nsid;
68:
69: int argc;
70: char **argv;
71: char **env;
72: };
73:
74:
75: static int
76: add_to_global (struct link_map *new)
77: {
78: struct link_map **new_global;
79: unsigned int to_add = 0;
80: unsigned int cnt;
81:
82:
83: for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
84: if (new->l_searchlist.r_list[cnt]->l_global == 0)
85: ++to_add;
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101: struct link_namespaces *ns = &GL(dl_ns)[new->l_ns];
102: if (ns->_ns_global_scope_alloc == 0)
103: {
104:
105: ns->_ns_global_scope_alloc
106: = ns->_ns_main_searchlist->r_nlist + to_add + 8;
107: new_global = (struct link_map **)
108: malloc (ns->_ns_global_scope_alloc * sizeof (struct link_map *));
109: if (new_global == NULL)
110: {
111: ns->_ns_global_scope_alloc = 0;
112: nomem:
113: _dl_signal_error (ENOMEM, new->l_libname->name, NULL,
114: N_("cannot extend global scope"));
115: return 1;
116: }
117:
118:
119: ns->_ns_main_searchlist->r_list
120: = memcpy (new_global, ns->_ns_main_searchlist->r_list,
121: (ns->_ns_main_searchlist->r_nlist
122: * sizeof (struct link_map *)));
123: }
124: else if (ns->_ns_main_searchlist->r_nlist + to_add
125: > ns->_ns_global_scope_alloc)
126: {
127:
128:
129: struct link_map **old_global
130: = GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list;
131: size_t new_nalloc = ((ns->_ns_global_scope_alloc + to_add) * 2);
132:
133: new_global = (struct link_map **)
134: malloc (new_nalloc * sizeof (struct link_map *));
135: if (new_global == NULL)
136: goto nomem;
137:
138: memcpy (new_global, old_global,
139: ns->_ns_global_scope_alloc * sizeof (struct link_map *));
140:
141: ns->_ns_global_scope_alloc = new_nalloc;
142: ns->_ns_main_searchlist->r_list = new_global;
143:
144: if (!RTLD_SINGLE_THREAD_P)
145: THREAD_GSCOPE_WAIT ();
146:
147: free (old_global);
148: }
149:
150:
151: unsigned int new_nlist = ns->_ns_main_searchlist->r_nlist;
152: for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
153: {
154: struct link_map *map = new->l_searchlist.r_list[cnt];
155:
156: if (map->l_global == 0)
157: {
158: map->l_global = 1;
159: ns->_ns_main_searchlist->r_list[new_nlist++] = map;
160: }
161: }
162: atomic_write_barrier ();
163: ns->_ns_main_searchlist->r_nlist = new_nlist;
164:
165: return 0;
166: }
167:
168: int
169: _dl_scope_free (void *old)
170: {
171: struct dl_scope_free_list *fsl;
172: #define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
173:
174: if (RTLD_SINGLE_THREAD_P)
175: free (old);
176: else if ((fsl = GL(dl_scope_free_list)) == NULL)
177: {
178: GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl));
179: if (fsl == NULL)
180: {
181: THREAD_GSCOPE_WAIT ();
182: free (old);
183: return 1;
184: }
185: else
186: {
187: fsl->list[0] = old;
188: fsl->count = 1;
189: }
190: }
191: else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE)
192: fsl->list[fsl->count++] = old;
193: else
194: {
195: THREAD_GSCOPE_WAIT ();
196: while (fsl->count > 0)
197: free (fsl->list[--fsl->count]);
198: return 1;
199: }
200: return 0;
201: }
202:
203: static void
204: dl_open_worker (void *a)
205: {
206: struct dl_open_args *args = a;
207: const char *file = args->file;
208: int mode = args->mode;
209: struct link_map *new;
210: int lazy;
211: unsigned int i;
212: bool any_tls = false;
213: struct link_map *call_map = NULL;
214:
215:
216: if (__check_caller (args->caller_dl_open,
217: allow_libc|allow_libdl|allow_ldso) != 0)
218: _dl_signal_error (0, "dlopen", NULL, N_("invalid caller"));
219:
220:
221:
222:
223:
224: const char *dst = strchr (file, '$');
225: if (dst != NULL || args->nsid == __LM_ID_CALLER
226: || strchr (file, '/') == NULL)
227: {
228: const void *caller_dlopen = args->caller_dlopen;
229:
230:
231:
232: call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
233:
234: struct link_map *l;
235: for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
236: for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
237: if (caller_dlopen >= (const void *) l->l_map_start
238: && caller_dlopen < (const void *) l->l_map_end
239: && (l->l_contiguous
240: || _dl_addr_inside_object (l, (ElfW(Addr)) caller_dlopen)))
241: {
242: assert (ns == l->l_ns);
243: call_map = l;
244: goto found_caller;
245: }
246:
247: found_caller:
248: if (args->nsid == __LM_ID_CALLER)
249: {
250: #ifndef SHARED
251:
252: if (call_map == NULL)
253: args->nsid = LM_ID_BASE;
254: else
255: #endif
256: args->nsid = call_map->l_ns;
257: }
258: }
259:
260: assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
261:
262:
263: if (__builtin_expect (dst != NULL, 0))
264: {
265: size_t len = strlen (file);
266: size_t required;
267: char *new_file;
268:
269:
270:
271: required = DL_DST_REQUIRED (call_map, file, len, _dl_dst_count (dst, 0));
272:
273:
274: new_file = (char *) alloca (required + 1);
275:
276:
277: _dl_dst_substitute (call_map, file, new_file, 0);
278:
279:
280: if (*new_file == '\0')
281: _dl_signal_error (0, "dlopen", NULL,
282: N_("empty dynamic string token substitution"));
283:
284:
285: file = new_file;
286:
287:
288:
289:
290: }
291:
292:
293: args->map = new = _dl_map_object (call_map, file, 0, lt_loaded, 0,
294: mode | __RTLD_CALLMAP, args->nsid);
295:
296:
297:
298: if (new == NULL)
299: {
300: assert (mode & RTLD_NOLOAD);
301: return;
302: }
303:
304: if (__builtin_expect (mode & __RTLD_SPROF, 0))
305:
306: return;
307:
308:
309: ++new->l_direct_opencount;
310:
311:
312: if (__builtin_expect (new->l_searchlist.r_list != NULL, 0))
313: {
314:
315: if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
316: _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
317: new->l_name, new->l_ns, new->l_direct_opencount);
318:
319:
320:
321: if ((mode & RTLD_GLOBAL) && new->l_global == 0)
322: (void) add_to_global (new);
323:
324: assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);
325:
326: return;
327: }
328:
329:
330: _dl_map_object_deps (new, NULL, 0, 0,
331: mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT));
332:
333:
334: for (i = 0; i < new->l_searchlist.r_nlist; ++i)
335: if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
336: (void) _dl_check_map_versions (new->l_searchlist.r_list[i]->l_real,
337: 0, 0);
338:
339: #ifdef SCOPE_DEBUG
340: show_scope (new);
341: #endif
342:
343: #ifdef SHARED
344:
345: if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
346: {
347: struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
348:
349: if (head->l_auditing == 0)
350: {
351: struct audit_ifaces *afct = GLRO(dl_audit);
352: for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
353: {
354: if (afct->activity != NULL)
355: afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
356:
357: afct = afct->next;
358: }
359: }
360: }
361: #endif
362:
363:
364: struct r_debug *r = _dl_debug_initialize (0, args->nsid);
365: r->r_state = RT_CONSISTENT;
366: _dl_debug_state ();
367:
368:
369: lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GLRO(dl_lazy);
370:
371:
372:
373:
374: struct link_map *l = new;
375: while (l->l_next)
376: l = l->l_next;
377: while (1)
378: {
379: if (! l->l_real->l_relocated)
380: {
381: #ifdef SHARED
382: if (__builtin_expect (GLRO(dl_profile) != NULL, 0))
383: {
384:
385:
386:
387:
388:
389: struct link_map *old_profile_map = GL(dl_profile_map);
390:
391: _dl_relocate_object (l, l->l_scope, 1, 1);
392:
393: if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
394: {
395:
396: _dl_start_profile ();
397:
398:
399: GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
400: }
401: }
402: else
403: #endif
404: _dl_relocate_object (l, l->l_scope, lazy, 0);
405: }
406:
407: if (l == new)
408: break;
409: l = l->l_prev;
410: }
411:
412:
413:
414: for (i = 0; i < new->l_searchlist.r_nlist; ++i)
415: {
416: struct link_map *imap = new->l_searchlist.r_list[i];
417:
418:
419:
420: if (imap->l_init_called && imap->l_type == lt_loaded)
421: {
422: struct r_scope_elem **runp = imap->l_scope;
423: size_t cnt = 0;
424:
425: while (*runp != NULL)
426: {
427: if (*runp == &new->l_searchlist)
428: break;
429: ++cnt;
430: ++runp;
431: }
432:
433: if (*runp != NULL)
434:
435: continue;
436:
437: if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
438: {
439:
440:
441: size_t new_size;
442: struct r_scope_elem **newp;
443:
444: #define SCOPE_ELEMS(imap) \
445: (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))
446:
447: if (imap->l_scope != imap->l_scope_mem
448: && imap->l_scope_max < SCOPE_ELEMS (imap))
449: {
450: new_size = SCOPE_ELEMS (imap);
451: newp = imap->l_scope_mem;
452: }
453: else
454: {
455: new_size = imap->l_scope_max * 2;
456: newp = (struct r_scope_elem **)
457: malloc (new_size * sizeof (struct r_scope_elem *));
458: if (newp == NULL)
459: _dl_signal_error (ENOMEM, "dlopen", NULL,
460: N_("cannot create scope list"));
461: }
462:
463: memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0]));
464: struct r_scope_elem **old = imap->l_scope;
465:
466: imap->l_scope = newp;
467:
468: if (old != imap->l_scope_mem)
469: _dl_scope_free (old);
470:
471: imap->l_scope_max = new_size;
472: }
473:
474:
475:
476:
477: imap->l_scope[cnt + 1] = NULL;
478: atomic_write_barrier ();
479: imap->l_scope[cnt] = &new->l_searchlist;
480: }
481:
482:
483: else if (! imap->l_init_called
484:
485: && __builtin_expect (imap->l_tls_blocksize > 0, 0))
486: {
487:
488:
489:
490: _dl_add_to_slotinfo (imap);
491:
492: if (imap->l_need_tls_init)
493: {
494: imap->l_need_tls_init = 0;
495: #ifdef SHARED
496:
497:
498: _dl_update_slotinfo (imap->l_tls_modid);
499: #endif
500:
501: GL(dl_init_static_tls) (imap);
502: assert (imap->l_need_tls_init == 0);
503: }
504:
505:
506: any_tls = true;
507: }
508: }
509:
510:
511: if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0))
512: _dl_fatal_printf (N_("\
513: TLS generation counter wrapped! Please report this."));
514:
515:
516: _dl_init (new, args->argc, args->argv, args->env);
517:
518:
519: if (mode & RTLD_GLOBAL)
520:
521: if (add_to_global (new) != 0)
522:
523: return;
524:
525:
526:
527: if (__builtin_expect (mode & RTLD_NODELETE, 0))
528: new->l_flags_1 |= DF_1_NODELETE;
529:
530: #ifndef SHARED
531:
532:
533: __libc_multiple_libcs = 1;
534: #endif
535:
536:
537: if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
538: _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
539: new->l_name, new->l_ns, new->l_direct_opencount);
540: }
541:
542:
543: void *
544: _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
545: int argc, char *argv[], char *env[])
546: {
547: if ((mode & RTLD_BINDING_MASK) == 0)
548:
549: _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()"));
550:
551:
552: __rtld_lock_lock_recursive (GL(dl_load_lock));
553:
554: if (nsid == LM_ID_NEWLM)
555: {
556:
557: for (nsid = 1; nsid < DL_NNS; ++nsid)
558: if (GL(dl_ns)[nsid]._ns_loaded == NULL)
559: break;
560:
561: if (nsid == DL_NNS)
562: {
563:
564: __rtld_lock_unlock_recursive (GL(dl_load_lock));
565:
566: _dl_signal_error (EINVAL, file, NULL, N_("\
567: no more namespaces available for dlmopen()"));
568: }
569:
570: _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT;
571: }
572:
573:
574: