1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * Copyright (c) 1988 AT&T
28 * All Rights Reserved
29 */
30
31 #include <string.h>
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <sys/mman.h>
36 #include <sys/debug.h>
37 #include <fcntl.h>
38 #include <limits.h>
39 #include <dlfcn.h>
40 #include <errno.h>
41 #include <link.h>
42 #include <debug.h>
43 #include <conv.h>
44 #include "_rtld.h"
45 #include "_audit.h"
46 #include "_elf.h"
47 #include "_inline_gen.h"
48 #include "msg.h"
49
50 /*
51 * If a load filter flag is in effect, and this object is a filter, trigger the
52 * loading of all its filtees. The load filter flag is in effect when creating
53 * configuration files, or when under the control of ldd(1), or the LD_LOADFLTR
54 * environment variable is set, or this object was built with the -zloadfltr
55 * flag. Otherwise, filtee loading is deferred until triggered by a relocation.
56 */
57 static void
load_filtees(Rt_map * lmp,int * in_nfavl)58 load_filtees(Rt_map *lmp, int *in_nfavl)
59 {
60 if ((FLAGS1(lmp) & MSK_RT_FILTER) &&
61 ((FLAGS(lmp) & FLG_RT_LOADFLTR) ||
62 (LIST(lmp)->lm_tflags & LML_TFLG_LOADFLTR))) {
63 Dyninfo *dip = DYNINFO(lmp);
64 uint_t cnt, max = DYNINFOCNT(lmp);
65 Slookup sl;
66
67 /*
68 * Initialize the symbol lookup data structure. Note, no symbol
69 * name is supplied. This NULL name causes filters to be loaded
70 * but no symbol to be searched for.
71 */
72 SLOOKUP_INIT(sl, 0, lmp, lmp, ld_entry_cnt, 0, 0, 0, 0, 0);
73
74 for (cnt = 0; cnt < max; cnt++, dip++) {
75 uint_t binfo;
76 Sresult sr;
77
78 SRESULT_INIT(sr, NULL);
79
80 if (((dip->di_flags & MSK_DI_FILTER) == 0) ||
81 ((dip->di_flags & FLG_DI_AUXFLTR) &&
82 (rtld_flags & RT_FL_NOAUXFLTR)))
83 continue;
84 (void) elf_lookup_filtee(&sl, &sr, &binfo, cnt,
85 in_nfavl);
86 }
87 }
88 }
89
90 /*
91 * Analyze one or more link-maps of a link map control list. This routine is
92 * called at startup to continue the processing of the main executable. It is
93 * also called each time a new set of objects are loaded, ie. from filters,
94 * lazy-loaded objects, or dlopen().
95 *
96 * In each instance we traverse the link-map control list starting with the
97 * initial object. As dependencies are analyzed they are added to the link-map
98 * control list. Thus the list grows as we traverse it - this results in the
99 * breadth first ordering of all needed objects.
100 *
101 * Return the initial link-map from which analysis starts for relocate_lmc().
102 */
103 Rt_map *
analyze_lmc(Lm_list * lml,Aliste nlmco,Rt_map * nlmp,Rt_map * clmp,int * in_nfavl)104 analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, Rt_map *clmp,
105 int *in_nfavl)
106 {
107 Rt_map *lmp;
108 Lm_cntl *nlmc;
109
110 /*
111 * If this link-map control list is being analyzed, return. The object
112 * that has just been added will be picked up by the existing analysis
113 * thread. Note, this is only really meaningful during process init-
114 * ialization, as objects are added to the main link-map control list.
115 * Following this initialization, each family of objects that are loaded
116 * are added to a new link-map control list.
117 */
118 /* LINTED */
119 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
120 if (nlmc->lc_flags & LMC_FLG_ANALYZING)
121 return (nlmp);
122
123 /*
124 * If this object doesn't belong to the present link-map control list
125 * then it must already have been analyzed, or it is in the process of
126 * being analyzed prior to us recursing into this analysis. In either
127 * case, ignore the object as it's already being taken care of.
128 */
129 if (nlmco != CNTL(nlmp))
130 return (nlmp);
131
132 nlmc->lc_flags |= LMC_FLG_ANALYZING;
133
134 for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
135 if (FLAGS(lmp) &
136 (FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE))
137 continue;
138
139 /*
140 * Indicate that analyzing is under way.
141 */
142 FLAGS(lmp) |= FLG_RT_ANALZING;
143
144 /*
145 * If this link map represents a relocatable object, then we
146 * need to finish the link-editing of the object at this point.
147 */
148 if (FLAGS(lmp) & FLG_RT_OBJECT) {
149 Rt_map *olmp;
150
151 if ((olmp = elf_obj_fini(lml, lmp, clmp,
152 in_nfavl)) == NULL) {
153 if (lml->lm_flags & LML_FLG_TRC_ENABLE)
154 continue;
155 nlmp = NULL;
156 break;
157 }
158
159 /*
160 * The original link-map that captured a relocatable
161 * object is a temporary link-map, that basically acts
162 * as a place holder in the link-map list. On
163 * completion of relocatable object processing, a new
164 * link-map is created, and switched with the place
165 * holder. Therefore, reassign both the present
166 * link-map pointer and the return link-map pointer.
167 * The former resets this routines link-map processing,
168 * while the latter provides for later functions, like
169 * relocate_lmc(), to start processing from this new
170 * link-map.
171 */
172 if (nlmp == lmp)
173 nlmp = olmp;
174 lmp = olmp;
175 }
176
177 DBG_CALL(Dbg_file_analyze(lmp));
178
179 /*
180 * Establish any dependencies this object requires.
181 */
182 if (LM_NEEDED(lmp)(lml, nlmco, lmp, in_nfavl) == 0) {
183 if (lml->lm_flags & LML_FLG_TRC_ENABLE)
184 continue;
185 nlmp = NULL;
186 break;
187 }
188
189 FLAGS(lmp) &= ~FLG_RT_ANALZING;
190 FLAGS(lmp) |= FLG_RT_ANALYZED;
191
192 /*
193 * If we're building a configuration file, determine if this
194 * object is a filter and if so load its filtees. This
195 * traversal is only necessary for crle(1), as typical use of
196 * an object will load filters as part of relocation processing.
197 */
198 if (MODE(nlmp) & RTLD_CONFGEN)
199 load_filtees(lmp, in_nfavl);
200
201 /*
202 * If an interposer has been added, it will have been inserted
203 * in the link-map before the link we're presently analyzing.
204 * Break out of this analysis loop and return to the head of
205 * the link-map control list to analyze the interposer. Note
206 * that this rescan preserves the breadth first loading of
207 * dependencies.
208 */
209 /* LINTED */
210 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
211 if (nlmc->lc_flags & LMC_FLG_REANALYZE) {
212 nlmc->lc_flags &= ~LMC_FLG_REANALYZE;
213 lmp = nlmc->lc_head;
214 }
215 }
216
217 /* LINTED */
218 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
219 nlmc->lc_flags &= ~LMC_FLG_ANALYZING;
220
221 return (nlmp);
222 }
223
224 /*
225 * Determine whether a symbol represents zero, .bss, bits. Most commonly this
226 * function is used to determine whether the data for a copy relocation refers
227 * to initialized data or .bss. If the data definition is within .bss, then the
228 * data is zero filled, and as the copy destination within the executable is
229 * .bss, we can skip copying zero's to zero's.
230 *
231 * However, if the defining object has MOVE data, it's .bss might contain
232 * non-zero data, in which case copy the definition regardless.
233 *
234 * For backward compatibility copy relocation processing, this routine can be
235 * used to determine precisely if a copy destination is a move record recipient.
236 */
237 static int
are_bits_zero(Rt_map * dlmp,Sym * dsym,int dest)238 are_bits_zero(Rt_map *dlmp, Sym *dsym, int dest)
239 {
240 mmapobj_result_t *mpp;
241 caddr_t daddr = (caddr_t)dsym->st_value;
242
243 if ((FLAGS(dlmp) & FLG_RT_FIXED) == 0)
244 daddr += ADDR(dlmp);
245
246 /*
247 * Determine the segment that contains the copy definition. Given that
248 * the copy relocation records have already been captured and verified,
249 * a segment must be found (but we add an escape clause never the less).
250 */
251 if ((mpp = find_segment(daddr, dlmp)) == NULL)
252 return (1);
253
254 /*
255 * If the definition is not within .bss, indicate this is not zero data.
256 */
257 if (daddr < (mpp->mr_addr + mpp->mr_offset + mpp->mr_fsize))
258 return (0);
259
260 /*
261 * If the definition is within .bss, make sure the definition isn't the
262 * recipient of a move record. Note, we don't precisely analyze whether
263 * the address is a move record recipient, as the infrastructure to
264 * prepare for, and carry out this analysis, is probably more costly
265 * than just copying the bytes regardless.
266 */
267 if ((FLAGS(dlmp) & FLG_RT_MOVE) == 0)
268 return (1);
269
270 /*
271 * However, for backward compatibility copy relocation processing, we
272 * can afford to work a little harder. Here, determine precisely
273 * whether the destination in the executable is a move record recipient.
274 * See comments in lookup_sym_interpose(), below.
275 */
276 if (dest && is_move_data(daddr))
277 return (0);
278
279 return (1);
280 }
281
282 /*
283 * Relocate an individual object.
284 */
285 static int
relocate_so(Lm_list * lml,Rt_map * lmp,int * relocated,int now,int * in_nfavl)286 relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now, int *in_nfavl)
287 {
288 APlist *textrel = NULL;
289 int ret = 1;
290
291 /*
292 * If we're running under ldd(1), and haven't been asked to trace any
293 * warnings, skip any actual relocation processing.
294 */
295 if (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||
296 (lml->lm_flags & LML_FLG_TRC_WARN)) {
297
298 if (relocated)
299 (*relocated)++;
300
301 if ((LM_RELOC(lmp)(lmp, now, in_nfavl, &textrel) == 0) &&
302 ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
303 ret = 0;
304
305 /*
306 * Finally process any move data. Note, this is carried out
307 * with ldd(1) under relocation processing too, as it can flush
308 * out move errors, and enables lari(1) to provide a true
309 * representation of the runtime bindings.
310 */
311 if ((FLAGS(lmp) & FLG_RT_MOVE) &&
312 (move_data(lmp, &textrel) == 0) &&
313 ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
314 ret = 0;
315 }
316
317 /*
318 * If a text segment was write enabled to perform any relocations or
319 * move records, then re-protect the segment by disabling writes.
320 */
321 if (textrel) {
322 mmapobj_result_t *mpp;
323 Aliste idx;
324
325 for (APLIST_TRAVERSE(textrel, idx, mpp))
326 (void) set_prot(lmp, mpp, 0);
327 free(textrel);
328 }
329
330 return (ret);
331 }
332
333 /*
334 * Relocate the objects on a link-map control list.
335 */
336 static int
_relocate_lmc(Lm_list * lml,Aliste lmco,Rt_map * nlmp,int * relocated,int * in_nfavl)337 _relocate_lmc(Lm_list *lml, Aliste lmco, Rt_map *nlmp, int *relocated,
338 int *in_nfavl)
339 {
340 Rt_map *lmp;
341
342 for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
343 /*
344 * If this object has already been relocated, we're done. If
345 * this object is being deleted, skip it, there's probably a
346 * relocation error somewhere that's causing this deletion.
347 */
348 if (FLAGS(lmp) &
349 (FLG_RT_RELOCING | FLG_RT_RELOCED | FLG_RT_DELETE))
350 continue;
351
352 /*
353 * Indicate that relocation processing is under way.
354 */
355 FLAGS(lmp) |= FLG_RT_RELOCING;
356
357 /*
358 * Relocate the object.
359 */
360 if (relocate_so(lml, lmp, relocated, 0, in_nfavl) == 0)
361 return (0);
362
363 /*
364 * Indicate that the objects relocation is complete.
365 */
366 FLAGS(lmp) &= ~FLG_RT_RELOCING;
367 FLAGS(lmp) |= FLG_RT_RELOCED;
368
369 /*
370 * If this object is being relocated on the main link-map list
371 * indicate that this object's init is available for harvesting.
372 * Objects that are being collected on other link-map lists
373 * will have there init availability tagged when the objects
374 * are move to the main link-map list (ie, after we know they,
375 * and their dependencies, are fully relocated and ready for
376 * use).
377 *
378 * Note, even under ldd(1) this init identification is necessary
379 * for -i (tsort) gathering.
380 */
381 if (lmco == ALIST_OFF_DATA) {
382 lml->lm_init++;
383 lml->lm_flags |= LML_FLG_OBJADDED;
384 }
385
386 /*
387 * Determine if this object is a filter, and if a load filter
388 * flag is in effect, trigger the loading of all its filtees.
389 */
390 load_filtees(lmp, in_nfavl);
391 }
392
393 /*
394 * Perform special copy relocations. These are only meaningful for
395 * dynamic executables (fixed and head of their link-map list). If
396 * this ever has to change then the infrastructure of COPY() has to
397 * change. Presently, a given link map can only have a receiver or
398 * supplier of copy data, so a union is used to overlap the storage
399 * for the COPY_R() and COPY_S() lists. These lists would need to
400 * be separated.
401 */
402 if ((FLAGS(nlmp) & FLG_RT_FIXED) && (nlmp == LIST(nlmp)->lm_head) &&
403 (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||
404 (lml->lm_flags & LML_FLG_TRC_WARN))) {
405 Rt_map *lmp;
406 Aliste idx1;
407 Word tracing;
408
409 #if defined(__i386)
410 if (elf_copy_gen(nlmp) == 0)
411 return (0);
412 #endif
413 if (COPY_S(nlmp) == NULL)
414 return (1);
415
416 if ((LIST(nlmp)->lm_flags & LML_FLG_TRC_ENABLE) &&
417 (((rtld_flags & RT_FL_SILENCERR) == 0) ||
418 (LIST(nlmp)->lm_flags & LML_FLG_TRC_VERBOSE)))
419 tracing = 1;
420 else
421 tracing = 0;
422
423 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
424
425 for (APLIST_TRAVERSE(COPY_S(nlmp), idx1, lmp)) {
426 Rel_copy *rcp;
427 Aliste idx2;
428
429 for (ALIST_TRAVERSE(COPY_R(lmp), idx2, rcp)) {
430 int zero;
431
432 /*
433 * Only copy the data if the data is from
434 * a non-zero definition (ie. not .bss).
435 */
436 zero = are_bits_zero(rcp->r_dlmp,
437 rcp->r_dsym, 0);
438 DBG_CALL(Dbg_reloc_copy(rcp->r_dlmp, nlmp,
439 rcp->r_name, zero));
440 if (zero)
441 continue;
442
443 (void) memcpy(rcp->r_radd, rcp->r_dadd,
444 rcp->r_size);
445
446 if ((tracing == 0) || ((FLAGS1(rcp->r_dlmp) &
447 FL1_RT_DISPREL) == 0))
448 continue;
449
450 (void) printf(MSG_INTL(MSG_LDD_REL_CPYDISP),
451 demangle(rcp->r_name), NAME(rcp->r_dlmp));
452 }
453 }
454
455 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
456
457 free(COPY_S(nlmp));
458 COPY_S(nlmp) = NULL;
459 }
460 return (1);
461 }
462
463 int
relocate_lmc(Lm_list * lml,Aliste nlmco,Rt_map * clmp,Rt_map * nlmp,int * in_nfavl)464 relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp,
465 int *in_nfavl)
466 {
467 int lret = 1, pret = 1;
468 APlist *alp;
469 Aliste plmco;
470 Lm_cntl *plmc, *nlmc;
471
472 /*
473 * If this link-map control list is being relocated, return. The object
474 * that has just been added will be picked up by the existing relocation
475 * thread. Note, this is only really meaningful during process init-
476 * ialization, as objects are added to the main link-map control list.
477 * Following this initialization, each family of objects that are loaded
478 * are added to a new link-map control list.
479 */
480 /* LINTED */
481 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
482
483 if (nlmc->lc_flags & LMC_FLG_RELOCATING)
484 return (1);
485
486 nlmc->lc_flags |= LMC_FLG_RELOCATING;
487
488 /*
489 * Relocate one or more link-maps of a link map control list. If this
490 * object doesn't belong to the present link-map control list then it
491 * must already have been relocated, or it is in the process of being
492 * relocated prior to us recursing into this relocation. In either
493 * case, ignore the object as it's already being taken care of, however,
494 * fall through and capture any relocation promotions that might have
495 * been established from the reference mode of this object.
496 *
497 * If we're generating a configuration file using crle(1), two passes
498 * may be involved. Under the first pass, RTLD_CONFGEN is set. Under
499 * this pass, crle() loads objects into the process address space. No
500 * relocation is necessary at this point, we simply need to analyze the
501 * objects to ensure any directly bound dependencies, filtees, etc.
502 * get loaded. Although we skip the relocation, fall through to ensure
503 * any control lists are maintained appropriately.
504 *
505 * If objects are to be dldump(3c)'ed, crle(1) makes a second pass,
506 * using RTLD_NOW and RTLD_CONFGEN. The RTLD_NOW effectively carries
507 * out the relocations of all loaded objects.
508 */
509 if ((nlmco == CNTL(nlmp)) &&
510 ((MODE(nlmp) & (RTLD_NOW | RTLD_CONFGEN)) != RTLD_CONFGEN)) {
511 int relocated = 0;
512
513 /*
514 * Determine whether the initial link-map control list has
515 * started relocation. From this point, should any interposing
516 * objects be added to this link-map control list, the objects
517 * are demoted to standard objects. Their interposition can't
518 * be guaranteed once relocations have been carried out.
519 */
520 if (nlmco == ALIST_OFF_DATA)
521 lml->lm_flags |= LML_FLG_STARTREL;
522
523 /*
524 * Relocate the link-map control list. Should this relocation
525 * fail, clean up this link-map list. Relocations within this
526 * list may have required relocation promotions on other lists,
527 * so before acting upon these, and possibly adding more objects
528 * to the present link-map control list, try and clean up any
529 * failed objects now.
530 */
531 lret = _relocate_lmc(lml, nlmco, nlmp, &relocated, in_nfavl);
532 if ((lret == 0) && (nlmco != ALIST_OFF_DATA))
533 remove_lmc(lml, clmp, nlmco, NAME(nlmp));
534 }
535
536 /*
537 * Determine the new, and previous link-map control lists.
538 */
539 /* LINTED */
540 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
541 if (nlmco == ALIST_OFF_DATA) {
542 plmco = nlmco;
543 plmc = nlmc;
544 } else {
545 plmco = nlmco - lml->lm_lists->al_size;
546 /* LINTED */
547 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco);
548 }
549
550 /*
551 * Having completed this control list of objects, they can now be bound
552 * to from other objects. Move this control list to the control list
553 * that precedes it. Although this control list may have only bound to
554 * controls lists much higher up the control list stack, it must only
555 * be moved up one control list so as to preserve the link-map order
556 * that may have already been traversed in search of symbols.
557 */
558 if (lret && (nlmco != ALIST_OFF_DATA) && nlmc->lc_head)
559 lm_move(lml, nlmco, plmco, nlmc, plmc);
560
561 /*
562 * Determine whether existing objects that have already been relocated,
563 * need any additional relocations performed. This can occur when new
564 * objects are loaded with RTLD_NOW, and these new objects have
565 * dependencies on objects that are already loaded. Note, that we peel
566 * any relocation promotions off of one control list at a time. This
567 * prevents relocations from being bound to objects that might yet fail
568 * to relocate themselves.
569 */
570 while ((alp = plmc->lc_now) != NULL) {
571 Aliste idx;
572 Rt_map *lmp;
573
574 /*
575 * Remove the relocation promotion list, as performing more
576 * relocations may result in discovering more objects that need
577 * promotion.
578 */
579 plmc->lc_now = NULL;
580
581 for (APLIST_TRAVERSE(alp, idx, lmp)) {
582 /*
583 * If the original relocation of the link-map control
584 * list failed, or one of the relocation promotions of
585 * this loop has failed, demote any pending objects
586 * relocation mode.
587 */
588 if ((lret == 0) || (pret == 0)) {
589 MODE(lmp) &= ~RTLD_NOW;
590 MODE(lmp) |= RTLD_LAZY;
591 continue;
592 }
593
594 /*
595 * If a relocation fails, save the error condition.
596 * It's possible that all new objects on the original
597 * link-map control list have been relocated
598 * successfully, but if the user request requires
599 * promoting objects that have already been loaded, we
600 * have to indicate that this operation couldn't be
601 * performed. The unrelocated objects are in use on
602 * another control list, and may continue to be used.
603 * If the .plt that resulted in the error is called,
604 * then the process will receive a fatal error at that
605 * time. But, the .plt may never be called.
606 */
607 if (relocate_so(lml, lmp, 0, 1, in_nfavl) == 0)
608 pret = 0;
609 }
610
611 /*
612 * Having promoted any objects, determine whether additional
613 * dependencies were added, and if so move them to the previous
614 * link-map control list.
615 */
616 /* LINTED */
617 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
618 /* LINTED */
619 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco);
620 if ((nlmco != ALIST_OFF_DATA) && nlmc->lc_head)
621 lm_move(lml, nlmco, plmco, nlmc, plmc);
622 free(alp);
623 }
624
625 /*
626 * If relocations have been successful, indicate that relocations are
627 * no longer active for this control list. Otherwise, leave the
628 * relocation flag, as this flag is used to determine the style of
629 * cleanup (see remove_lmc()).
630 */
631 if (lret && pret) {
632 /* LINTED */
633 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
634 nlmc->lc_flags &= ~LMC_FLG_RELOCATING;
635
636 return (1);
637 }
638
639 return (0);
640 }
641
642 /*
643 * Inherit the first rejection message for possible later diagnostics.
644 *
645 * Any attempt to process a file that is unsuccessful, should be accompanied
646 * with an error diagnostic. However, some operations like searching for a
647 * simple filename, involve trying numerous paths, and an error message for each
648 * lookup is not required. Although a multiple search can fail, it's possible
649 * that a file was found, but was rejected because it was the wrong type.
650 * To satisfy these possibilities, the first failure is recorded as a rejection
651 * message, and this message is used later for a more specific diagnostic.
652 *
653 * File searches are focused at load_one(), and from here a rejection descriptor
654 * is passed down to various child routines. If these child routines can
655 * process multiple files, then they will maintain their own rejection desc-
656 * riptor. This is filled in for any failures, and a diagnostic produced to
657 * reflect the failure. The child routines then employ rejection_inherit() to
658 * pass the first rejection message back to load_one().
659 *
660 * Note that the name, and rejection string must be duplicated, as the name
661 * buffer and error string buffer (see conv_ routines) may be reused for
662 * additional processing or rejection messages.
663 */
664 void
rejection_inherit(Rej_desc * rej1,Rej_desc * rej2)665 rejection_inherit(Rej_desc *rej1, Rej_desc *rej2)
666 {
667 if (rej2->rej_type && (rej1->rej_type == 0)) {
668 rej1->rej_type = rej2->rej_type;
669 rej1->rej_info = rej2->rej_info;
670 rej1->rej_flags = rej2->rej_flags;
671 if (rej2->rej_name)
672 rej1->rej_name = stravl_insert(rej2->rej_name, 0, 0, 0);
673 if ((rej2->rej_str) && ((rej1->rej_str =
674 stravl_insert(rej2->rej_str, 0, 0, 0)) == NULL))
675 rej1->rej_str = MSG_ORIG(MSG_EMG_ENOMEM);
676 }
677 }
678
679 /*
680 * Helper routine for is_so_matched() that consolidates matching a path name,
681 * or file name component of a link-map name.
682 */
683 inline static int
_is_so_matched(const char * name,const char * str,int path)684 _is_so_matched(const char *name, const char *str, int path)
685 {
686 const char *_str;
687
688 if ((path == 0) && ((_str = strrchr(str, '/')) != NULL))
689 _str++;
690 else
691 _str = str;
692
693 return (strcmp(name, _str));
694 }
695
696 /*
697 * Determine whether a search name matches one of the names associated with a
698 * link-map. A link-map contains several names:
699 *
700 * - a NAME() - this is the basename of the dynamic executable that started
701 * the process, and the path name of any dependencies used by the process.
702 * Most executables are received as full path names, as exec() prepends a
703 * search $PATH to locate the executable. However, simple file names can
704 * be received from exec() if the file is executed from the present working
705 * directory. Regardless, ld.so.1 maintains NAME() as the basename, as
706 * this has always been the name used in diagnostics and error messages.
707 * Most dependencies are full path names, as the typical search for a
708 * dependency, say "libx.so.1", results in search paths being prepended to
709 * the name, which eventually open "/lib/libx.so.1". However, relative
710 * path names can be supplied as dependencies, e.g. dlopen("../libx.so.1").
711 *
712 * - a PATHNAME() - this is the fully resolved path name of the object. This
713 * name will differ from NAME() for all dynamic executables, and may differ
714 * from the NAME() of dependencies, if the dependency is not a full path
715 * name, or the dependency resolves to a symbolic link.
716 *
717 * - an ALIAS() name - these are alternative names by which the object has
718 * been found, ie. when dependencies are loaded through a variety of
719 * different symbolic links.
720 *
721 * The name pattern matching can differ depending on whether we are looking
722 * for a full path name (path != 0), or a simple file name (path == 0). Full
723 * path names typically match NAME() or PATHNAME() entries.
724 *
725 * For all full path name searches, the link-map names are taken as is. For
726 * simple file name searches, only the file name component of any link-map
727 * names are used for comparison.
728 */
729 inline static Rt_map *
is_so_matched(Rt_map * lmp,const char * name,int path)730 is_so_matched(Rt_map *lmp, const char *name, int path)
731 {
732 Aliste idx;
733 const char *cp;
734
735 if (_is_so_matched(name, NAME(lmp), path) == 0)
736 return (lmp);
737
738 if (PATHNAME(lmp) != NAME(lmp)) {
739 if (_is_so_matched(name, PATHNAME(lmp), path) == 0)
740 return (lmp);
741 }
742
743 for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) {
744 if (_is_so_matched(name, cp, path) == 0)
745 return (lmp);
746 }
747
748 return (NULL);
749 }
750
751 /*
752 * Files are opened by ld.so.1 to satisfy dependencies, filtees and dlopen()
753 * requests. Each request investigates the file based upon the callers
754 * environment. Once a full path name has been established, the following
755 * checks are made:
756 *
757 * - does the path exist in the link-map lists FullPathNode AVL tree? if
758 * so, the file is already loaded, and its associated link-map pointer
759 * is returned.
760 * - does the path exist in the not-found AVL tree? if so, this path has
761 * already been determined to not exist, and a failure is returned.
762 * - a device/inode check, to ensure the same file isn't mapped multiple
763 * times through different paths. See file_open().
764 *
765 * However, there are cases where a test for an existing file name needs to be
766 * carried out, such as dlopen(NOLOAD) requests, dldump() requests, and as a
767 * final fallback to dependency loading. These requests are handled by
768 * is_so_loaded().
769 *
770 * A traversal through the callers link-map list is carried out, and from each
771 * link-map, a comparison is made against all of the various names by which the
772 * object has been referenced. is_so_matched() is used to compare the link-map
773 * names against the name being searched for. Whether the search name is a full
774 * path name or a simple file name, governs what comparisons are made.
775 *
776 * A full path name, which is a fully resolved path name that starts with a "/"
777 * character, or a relative path name that includes a "/" character, must match
778 * the link-map names exactly. A simple file name, which is any name *not*
779 * containing a "/" character, are matched against the file name component of
780 * any link-map names.
781 */
782 Rt_map *
is_so_loaded(Lm_list * lml,const char * name,int * in_nfavl)783 is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl)
784 {
785 Rt_map *lmp;
786 avl_index_t where;
787 Lm_cntl *lmc;
788 Aliste idx;
789 int path = 0;
790
791 /*
792 * If the name is a full path name, first determine if the path name is
793 * registered on the FullPathNode AVL, or not-found AVL trees.
794 */
795 if (name[0] == '/') {
796 uint_t hash = sgs_str_hash(name);
797
798 if (((lmp = fpavl_recorded(lml, name, hash, &where)) != NULL) &&
799 ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0))
800 return (lmp);
801
802 if (pnavl_recorded(&nfavl, name, hash, NULL)) {
803 /*
804 * For dlopen() and dlsym() fall backs, indicate that
805 * a registered not-found path has indicated that this
806 * object does not exist.
807 */
808 if (in_nfavl)
809 (*in_nfavl)++;
810 return (NULL);
811 }
812 }
813
814 /*
815 * Determine whether the name is a simple file name, or a path name.
816 */
817 if (strchr(name, '/'))
818 path++;
819
820 /*
821 * Loop through the callers link-map lists.
822 */
823 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
824 for (lmp = lmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
825 if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE))
826 continue;
827
828 if (is_so_matched(lmp, name, path))
829 return (lmp);
830 }
831 }
832 return (NULL);
833 }
834
835 /*
836 * Tracing is enabled by the LD_TRACE_LOADED_OPTIONS environment variable which
837 * is normally set from ldd(1). For each link map we load, print the load name
838 * and the full pathname of the associated object.
839 */
840 /* ARGSUSED4 */
841 static void
trace_so(Rt_map * clmp,Rej_desc * rej,const char * name,const char * path,int alter,const char * nfound)842 trace_so(Rt_map *clmp, Rej_desc *rej, const char *name, const char *path,
843 int alter, const char *nfound)
844 {
845 const char *str = MSG_ORIG(MSG_STR_EMPTY);
846 const char *reject = MSG_ORIG(MSG_STR_EMPTY);
847 char _reject[PATH_MAX];
848
849 /*
850 * The first time through trace_so() will only have lddstub on the
851 * link-map list and the preloaded shared object is supplied as "path".
852 * As we don't want to print this shared object as a dependency, but
853 * instead inspect *its* dependencies, return.
854 */
855 if (FLAGS1(clmp) & FL1_RT_LDDSTUB)
856 return;
857
858 /*
859 * Without any rejection info, this is a supplied not-found condition.
860 */
861 if (rej && (rej->rej_type == 0)) {
862 (void) printf(nfound, name);
863 return;
864 }
865
866 /*
867 * If rejection information exists then establish what object was
868 * found and the reason for its rejection.
869 */
870 if (rej) {
871 Conv_reject_desc_buf_t rej_buf;
872
873 /* LINTED */
874 (void) snprintf(_reject, PATH_MAX,
875 MSG_INTL(ldd_reject[rej->rej_type]),
876 conv_reject_desc(rej, &rej_buf, M_MACH));
877 if (rej->rej_name)
878 path = rej->rej_name;
879 reject = (char *)_reject;
880
881 /*
882 * Was an alternative pathname defined (from a configuration
883 * file).
884 */
885 if (rej->rej_flags & FLG_REJ_ALTER)
886 str = MSG_INTL(MSG_LDD_FIL_ALTER);
887 } else {
888 if (alter)
889 str = MSG_INTL(MSG_LDD_FIL_ALTER);
890 }
891
892 /*
893 * If the load name isn't a full pathname print its associated pathname
894 * together with all the other information we've gathered.
895 */
896 if (*name == '/')
897 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), path, str, reject);
898 else
899 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), name, path, str,
900 reject);
901 }
902
903 /*
904 * Establish a link-map mode, initializing it if it has just been loaded, or
905 * potentially updating it if it already exists.
906 */
907 int
update_mode(Rt_map * lmp,int omode,int nmode)908 update_mode(Rt_map *lmp, int omode, int nmode)
909 {
910 Lm_list *lml = LIST(lmp);
911 int pmode = 0;
912
913 /*
914 * A newly loaded object hasn't had its mode set yet. Modes are used to
915 * load dependencies, so don't propagate any parent or no-load flags, as
916 * these would adversely affect this objects ability to load any of its
917 * dependencies that aren't already loaded. RTLD_FIRST is applicable to
918 * this objects handle creation only, and should not be propagated.
919 */
920 if ((FLAGS(lmp) & FLG_RT_MODESET) == 0) {
921 MODE(lmp) |= nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST);
922 FLAGS(lmp) |= FLG_RT_MODESET;
923 return (1);
924 }
925
926 /*
927 * Establish any new overriding modes. RTLD_LAZY and RTLD_NOW should be
928 * represented individually (this is historic, as these two flags were
929 * the only flags originally available to dlopen()). Other flags are
930 * accumulative, but have a hierarchy of preference.
931 */
932 if ((omode & RTLD_LAZY) && (nmode & RTLD_NOW)) {
933 MODE(lmp) &= ~RTLD_LAZY;
934 pmode |= RTLD_NOW;
935 }
936
937 pmode |= ((~omode & nmode) &
938 (RTLD_GLOBAL | RTLD_WORLD | RTLD_NODELETE));
939 if (pmode) {
940 DBG_CALL(Dbg_file_mode_promote(lmp, pmode));
941 MODE(lmp) |= pmode;
942 }
943
944 /*
945 * If this load is an RTLD_NOW request and the object has already been
946 * loaded non-RTLD_NOW, append this object to the relocation-now list
947 * of the objects associated control list. Note, if the object hasn't
948 * yet been relocated, setting its MODE() to RTLD_NOW will establish
949 * full relocation processing when it eventually gets relocated.
950 */
951 if ((pmode & RTLD_NOW) &&
952 (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))) {
953 Lm_cntl *lmc;
954
955 /* LINTED */
956 lmc = (Lm_cntl *)alist_item_by_offset(LIST(lmp)->lm_lists,
957 CNTL(lmp));
958 (void) aplist_append(&lmc->lc_now, lmp, AL_CNT_LMNOW);
959 }
960
961 /*
962 * If this objects .init has been collected but has not yet been called,
963 * it may be necessary to reevaluate the object using tsort(). For
964 * example, a new dlopen() hierarchy may bind to uninitialized objects
965 * that are already loaded, or a dlopen(RTLD_NOW) can establish new
966 * bindings between already loaded objects that require the tsort()
967 * information be recomputed. If however, no new objects have been
968 * added to the process, and this object hasn't been promoted, don't
969 * bother reevaluating the .init. The present tsort() information is
970 * probably as accurate as necessary, and by not establishing a parallel
971 * tsort() we can help reduce the amount of recursion possible between
972 * .inits.
973 */
974 if (((FLAGS(lmp) &
975 (FLG_RT_INITCLCT | FLG_RT_INITCALL)) == FLG_RT_INITCLCT) &&
976 ((lml->lm_flags & LML_FLG_OBJADDED) || ((pmode & RTLD_NOW) &&
977 (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))))) {
978 FLAGS(lmp) &= ~FLG_RT_INITCLCT;
979 LIST(lmp)->lm_init++;
980 LIST(lmp)->lm_flags |= LML_FLG_OBJREEVAL;
981 }
982
983 return (pmode);
984 }
985
986 /*
987 * Determine whether an alias name already exists, and if not create one. This
988 * is typically used to retain dependency names, such as "libc.so.1", which
989 * would have been expanded to full path names when they were loaded. The
990 * full path names (NAME() and possibly PATHNAME()) are maintained on the
991 * FullPathNode AVL tree, and thus would have been matched by fpavl_loaded()
992 * during file_open().
993 */
994 int
append_alias(Rt_map * lmp,const char * str,int * added)995 append_alias(Rt_map *lmp, const char *str, int *added)
996 {
997 const char *cp;
998 Aliste idx;
999
1000 /*
1001 * Determine if this filename is already on the alias list.
1002 */
1003 for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) {
1004 if (strcmp(cp, str) == 0)
1005 return (1);
1006 }
1007
1008 /*
1009 * This is a new alias, append it to the alias list.
1010 */
1011 if (((cp = stravl_insert(str, 0, 0, 0)) == NULL) ||
1012 (aplist_append(&ALIAS(lmp), cp, AL_CNT_ALIAS) == NULL))
1013 return (0);
1014
1015 if (added)
1016 *added = 1;
1017 return (1);
1018 }
1019
1020 /*
1021 * Determine whether a file is already loaded by comparing device and inode
1022 * values.
1023 */
1024 static Rt_map *
is_devinode_loaded(rtld_stat_t * status,Lm_list * lml,const char * name,uint_t flags)1025 is_devinode_loaded(rtld_stat_t *status, Lm_list *lml, const char *name,
1026 uint_t flags)
1027 {
1028 Lm_cntl *lmc;
1029 Aliste idx;
1030
1031 /*
1032 * If this is an auditor, it will have been opened on a new link-map.
1033 * To prevent multiple occurrences of the same auditor on multiple
1034 * link-maps, search the head of each link-map list and see if this
1035 * object is already loaded as an auditor.
1036 */
1037 if (flags & FLG_RT_AUDIT) {
1038 Lm_list *lml;
1039
1040 for (APLIST_TRAVERSE(dynlm_list, idx, lml)) {
1041 Rt_map *nlmp = lml->lm_head;
1042
1043 if (nlmp && ((FLAGS(nlmp) &
1044 (FLG_RT_AUDIT | FLG_RT_DELETE)) == FLG_RT_AUDIT) &&
1045 (STDEV(nlmp) == status->st_dev) &&
1046 (STINO(nlmp) == status->st_ino))
1047 return (nlmp);
1048 }
1049 return (NULL);
1050 }
1051
1052 /*
1053 * If the file has been found determine from the new files status
1054 * information if this file is actually linked to one we already have
1055 * mapped. This catches symlink names not caught by is_so_loaded().
1056 */
1057 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
1058 Rt_map *nlmp;
1059
1060 for (nlmp = lmc->lc_head; nlmp; nlmp = NEXT_RT_MAP(nlmp)) {
1061 if ((FLAGS(nlmp) & FLG_RT_DELETE) ||
1062 (FLAGS1(nlmp) & FL1_RT_LDDSTUB))
1063 continue;
1064
1065 if ((STDEV(nlmp) != status->st_dev) ||
1066 (STINO(nlmp) != status->st_ino))
1067 continue;
1068
1069 if (lml->lm_flags & LML_FLG_TRC_VERBOSE) {
1070 /* BEGIN CSTYLED */
1071 if (*name == '/')
1072 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH),
1073 name, MSG_ORIG(MSG_STR_EMPTY),
1074 MSG_ORIG(MSG_STR_EMPTY));
1075 else
1076 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV),
1077 name, NAME(nlmp),
1078 MSG_ORIG(MSG_STR_EMPTY),
1079 MSG_ORIG(MSG_STR_EMPTY));
1080 /* END CSTYLED */
1081 }
1082 return (nlmp);
1083 }
1084 }
1085 return (NULL);
1086 }
1087
1088 /*
1089 * Generate any error messages indicating a file could not be found. When
1090 * preloading or auditing a secure application, it can be a little more helpful
1091 * to indicate that a search of secure directories has failed, so adjust the
1092 * messages accordingly.
1093 */
1094 void
file_notfound(Lm_list * lml,const char * name,Rt_map * clmp,uint_t flags,Rej_desc * rej)1095 file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags,
1096 Rej_desc *rej)
1097 {
1098 int secure = 0;
1099
1100 if ((rtld_flags & RT_FL_SECURE) &&
1101 (flags & (FLG_RT_PRELOAD | FLG_RT_AUDIT)))
1102 secure++;
1103
1104 if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
1105 /*
1106 * Under ldd(1), auxiliary filtees that can't be loaded are
1107 * ignored, unless verbose errors are requested.
1108 */
1109 if ((rtld_flags & RT_FL_SILENCERR) &&
1110 ((lml->lm_flags & LML_FLG_TRC_VERBOSE) == 0))
1111 return;
1112
1113 if (secure)
1114 trace_so(clmp, rej, name, 0, 0,
1115 MSG_INTL(MSG_LDD_SEC_NFOUND));
1116 else
1117 trace_so(clmp, rej, name, 0, 0,
1118 MSG_INTL(MSG_LDD_FIL_NFOUND));
1119 return;
1120 }
1121
1122 if (rej->rej_type) {
1123 Conv_reject_desc_buf_t rej_buf;
1124
1125 eprintf(lml, ERR_FATAL, MSG_INTL(err_reject[rej->rej_type]),
1126 rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN),
1127 conv_reject_desc(rej, &rej_buf, M_MACH));
1128 return;
1129 }
1130
1131 if (secure)
1132 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SEC_OPEN), name);
1133 else
1134 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), name,
1135 strerror(ENOENT));
1136 }
1137
1138 static int
file_open(int err,Lm_list * lml,Rt_map * clmp,uint_t flags,Fdesc * fdp,Rej_desc * rej,int * in_nfavl)1139 file_open(int err, Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp,
1140 Rej_desc *rej, int *in_nfavl)
1141 {
1142 rtld_stat_t status;
1143 Rt_map *nlmp;
1144 avl_index_t nfavlwhere = 0;
1145 const char *oname = fdp->fd_oname, *nname = fdp->fd_nname;
1146 uint_t hash = sgs_str_hash(nname);
1147
1148
1149 if ((nname = stravl_insert(fdp->fd_nname, hash, 0, 0)) == NULL)
1150 return (0);
1151 fdp->fd_nname = nname;
1152
1153 if ((err == 0) && (fdp->fd_flags & FLG_FD_ALTER))
1154 DBG_CALL(Dbg_file_config_obj(lml, oname, 0, nname));
1155
1156 /*
1157 * If we're dealing with a full pathname, determine whether this
1158 * pathname is already known. Other pathnames fall through to the
1159 * dev/inode check, as even though the pathname may look the same as
1160 * one previously used, the process may have changed directory.
1161 */
1162 if ((err == 0) && (nname[0] == '/')) {
1163 if ((nlmp = fpavl_recorded(lml, nname, hash,
1164 &(fdp->fd_avlwhere))) != NULL) {
1165 fdp->fd_lmp = nlmp;
1166 return (1);
1167 }
1168 if (pnavl_recorded(&nfavl, nname, hash, &nfavlwhere)) {
1169 /*
1170 * For dlopen() and dlsym() fall backs, indicate that
1171 * a registered not-found path has indicated that this
1172 * object does not exist. If this path has been
1173 * constructed as part of expanding a CAPABILITY
1174 * directory, this is a silent failure, where no
1175 * rejection message is created.
1176 */
1177 if (in_nfavl)
1178 (*in_nfavl)++;
1179 return (0);
1180 }
1181 }
1182
1183 if ((err == 0) && ((rtld_stat(nname, &status)) != -1)) {
1184 char path[PATH_MAX];
1185 int fd, size, added;
1186
1187 /*
1188 * If this path has been constructed as part of expanding a
1189 * CAPABILITY directory, ignore any subdirectories. As this
1190 * is a silent failure, no rejection message is created. For
1191 * any other reference that expands to a directory, fall
1192 * through to construct a meaningful rejection message.
1193 */
1194 if ((flags & FLG_RT_CAP) &&
1195 ((status.st_mode & S_IFMT) == S_IFDIR))
1196 return (0);
1197
1198 /*
1199 * If this is a directory (which can't be mmap()'ed) generate a
1200 * precise error message.
1201 */
1202 if ((status.st_mode & S_IFMT) == S_IFDIR) {
1203 rej->rej_name = nname;
1204 if (fdp->fd_flags & FLG_FD_ALTER)
1205 rej->rej_flags = FLG_REJ_ALTER;
1206 rej->rej_type = SGS_REJ_STR;
1207 rej->rej_str = strerror(EISDIR);
1208 DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH));
1209 return (0);
1210 }
1211
1212 /*
1213 * Resolve the filename and determine whether the resolved name
1214 * is already known. Typically, the previous fpavl_loaded()
1215 * will have caught this, as both NAME() and PATHNAME() for a
1216 * link-map are recorded in the FullPathNode AVL tree. However,
1217 * instances exist where a file can be replaced (loop-back
1218 * mounts, bfu, etc.), and reference is made to the original
1219 * file through a symbolic link. By checking the pathname here,
1220 * we don't fall through to the dev/inode check and conclude
1221 * that a new file should be loaded.
1222 */
1223 if ((nname[0] == '/') &&
1224 ((size = resolvepath(nname, path, (PATH_MAX - 1))) > 0)) {
1225 path[size] = '\0';
1226
1227 fdp->fd_flags |= FLG_FD_RESOLVED;
1228
1229 if (strcmp(nname, path)) {
1230 if ((nlmp =
1231 fpavl_recorded(lml, path, 0, 0)) != NULL) {
1232 added = 0;
1233
1234 if (append_alias(nlmp, nname,
1235 &added) == 0)
1236 return (0);
1237 /* BEGIN CSTYLED */
1238 if (added)
1239 DBG_CALL(Dbg_file_skip(LIST(clmp),
1240 NAME(nlmp), nname));
1241 /* END CSTYLED */
1242 fdp->fd_lmp = nlmp;
1243 return (1);
1244 }
1245
1246 /*
1247 * If this pathname hasn't been loaded, save
1248 * the resolved pathname so that it doesn't
1249 * have to be recomputed as part of fullpath()
1250 * processing.
1251 */
1252 if ((fdp->fd_pname = stravl_insert(path, 0,
1253 (size + 1), 0)) == NULL)
1254 return (0);
1255 }
1256 }
1257
1258 nlmp = is_devinode_loaded(&status, lml, nname, flags);
1259 if (nlmp != NULL) {
1260 if (flags & FLG_RT_AUDIT) {
1261 /*
1262 * If we've been requested to load an auditor,
1263 * and an auditor of the same name already
1264 * exists, then the original auditor is used.
1265 */
1266 DBG_CALL(Dbg_audit_skip(LIST(clmp),
1267 NAME(nlmp), LIST(nlmp)->lm_lmidstr));
1268 } else {
1269 /*
1270 * Otherwise, if an alternatively named file
1271 * has been found for the same dev/inode, add
1272 * a new name alias. Insert any alias full path
1273 * name in the FullPathNode AVL tree.
1274 */
1275 added = 0;
1276
1277 if (append_alias(nlmp, nname, &added) == 0)
1278 return (0);
1279 if (added) {
1280 if ((nname[0] == '/') &&
1281 (fpavl_insert(lml, nlmp,
1282 nname, 0) == 0))
1283 return (0);
1284 DBG_CALL(Dbg_file_skip(LIST(clmp),
1285 NAME(nlmp), nname));
1286 }
1287 }
1288
1289 /*
1290 * Record in the file descriptor the existing object
1291 * that satisfies this open request.
1292 */
1293 fdp->fd_lmp = nlmp;
1294 return (1);
1295 }
1296
1297 if ((fd = open(nname, O_RDONLY, 0)) == -1) {
1298 /*
1299 * As the file must exist for the previous stat() to
1300 * have succeeded, record the error condition.
1301 */
1302 rej->rej_type = SGS_REJ_STR;
1303 rej->rej_str = strerror(errno);
1304 } else {
1305 /*
1306 * Map the object. A successful return indicates that
1307 * the object is appropriate for ld.so.1 processing.
1308 */
1309 fdp->fd_ftp = map_obj(lml, fdp, status.st_size, nname,
1310 fd, rej);
1311 (void) close(fd);
1312
1313 if (fdp->fd_ftp != NULL) {
1314 fdp->fd_dev = status.st_dev;
1315 fdp->fd_ino = status.st_ino;
1316 return (1);
1317 }
1318 }
1319
1320 } else if (errno != ENOENT) {
1321 /*
1322 * If the open() failed for anything other than the file not
1323 * existing, record the error condition.
1324 */
1325 rej->rej_type = SGS_REJ_STR;
1326 rej->rej_str = strerror(errno);
1327 }
1328
1329 /*
1330 * Regardless of error, duplicate and record any full path names that
1331 * can't be used on the "not-found" AVL tree.
1332 */
1333 if (nname[0] == '/')
1334 nfavl_insert(nname, nfavlwhere);
1335
1336 /*
1337 * Indicate any rejection.
1338 */
1339 if (rej->rej_type) {
1340 rej->rej_name = nname;
1341 if (fdp->fd_flags & FLG_FD_ALTER)
1342 rej->rej_flags = FLG_REJ_ALTER;
1343 DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH));
1344 }
1345 return (0);
1346 }
1347
1348 /*
1349 * Find a full pathname (it contains a "/").
1350 */
1351 int
find_path(Lm_list * lml,Rt_map * clmp,uint_t flags,Fdesc * fdp,Rej_desc * rej,int * in_nfavl)1352 find_path(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
1353 int *in_nfavl)
1354 {
1355 const char *oname = fdp->fd_oname;
1356 int err = 0;
1357
1358 /*
1359 * If directory configuration exists determine if this path is known.
1360 */
1361 if (rtld_flags & RT_FL_DIRCFG) {
1362 Rtc_obj *obj;
1363 const char *aname;
1364
1365 if ((obj = elf_config_ent(oname, (Word)elf_hash(oname),
1366 0, &aname)) != 0) {
1367 /*
1368 * If the configuration file states that this path is a
1369 * directory, or the path is explicitly defined as
1370 * non-existent (ie. a unused platform specific
1371 * library), then go no further.
1372 */
1373 if (obj->co_flags & RTC_OBJ_DIRENT) {
1374 err = EISDIR;
1375 } else if ((obj->co_flags &
1376 (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
1377 RTC_OBJ_NOEXIST) {
1378 err = ENOENT;
1379 } else if ((obj->co_flags & RTC_OBJ_ALTER) &&
1380 (rtld_flags & RT_FL_OBJALT) && (lml == &lml_main)) {
1381 int ret;
1382
1383 fdp->fd_flags |= FLG_FD_ALTER;
1384 fdp->fd_nname = aname;
1385
1386 /*
1387 * Attempt to open the alternative path. If
1388 * this fails, and the alternative is flagged
1389 * as optional, fall through to open the
1390 * original path.
1391 */
1392 DBG_CALL(Dbg_libs_found(lml, aname,
1393 FLG_FD_ALTER));
1394 ret = file_open(0, lml, clmp, flags, fdp,
1395 rej, in_nfavl);
1396 if (ret || ((obj->co_flags &
1397 RTC_OBJ_OPTINAL) == 0))
1398 return (ret);
1399
1400 fdp->fd_flags &= ~FLG_FD_ALTER;
1401 }
1402 }
1403 }
1404 DBG_CALL(Dbg_libs_found(lml, oname, 0));
1405 fdp->fd_nname = oname;
1406 return (file_open(err, lml, clmp, flags, fdp, rej, in_nfavl));
1407 }
1408
1409 /*
1410 * Find a simple filename (it doesn't contain a "/").
1411 */
1412 static int
_find_file(Lm_list * lml,Rt_map * clmp,uint_t flags,Fdesc * fdp,Rej_desc * rej,Pdesc * pdp,int aflag,int * in_nfavl)1413 _find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
1414 Pdesc *pdp, int aflag, int *in_nfavl)
1415 {
1416 const char *nname = fdp->fd_nname;
1417
1418 DBG_CALL(Dbg_libs_found(lml, nname, aflag));
1419 if ((lml->lm_flags & LML_FLG_TRC_SEARCH) &&
1420 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
1421 (void) printf(MSG_INTL(MSG_LDD_PTH_TRYING), nname, aflag ?
1422 MSG_INTL(MSG_LDD_FIL_ALTER) : MSG_ORIG(MSG_STR_EMPTY));
1423 }
1424
1425 /*
1426 * If we're being audited tell the audit library of the file we're about
1427 * to go search for. The audit library may offer an alternative
1428 * dependency, or indicate that this dependency should be ignored.
1429 */
1430 if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
1431 char *aname;
1432
1433 if ((aname = audit_objsearch(clmp, nname,
1434 (pdp->pd_flags & LA_SER_MASK))) == NULL) {
1435 DBG_CALL(Dbg_audit_terminate(lml, nname));
1436 return (0);
1437 }
1438
1439 if (aname != nname) {
1440 fdp->fd_flags &= ~FLG_FD_SLASH;
1441 fdp->fd_nname = aname;
1442 }
1443 }
1444 return (file_open(0, lml, clmp, flags, fdp, rej, in_nfavl));
1445 }
1446
1447 static int
find_file(Lm_list * lml,Rt_map * clmp,uint_t flags,Fdesc * fdp,Rej_desc * rej,Pdesc * pdp,Word * strhash,int * in_nfavl)1448 find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
1449 Pdesc *pdp, Word *strhash, int *in_nfavl)
1450 {
1451 static Rtc_obj Obj = { 0 };
1452 Rtc_obj *dobj;
1453 const char *oname = fdp->fd_oname;
1454 size_t olen = strlen(oname);
1455
1456 if (pdp->pd_pname == NULL)
1457 return (0);
1458 if (pdp->pd_info) {
1459 dobj = (Rtc_obj *)pdp->pd_info;
1460 if ((dobj->co_flags &
1461 (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1462 return (0);
1463 } else
1464 dobj = NULL;
1465
1466 /*
1467 * If configuration information exists see if this directory/file
1468 * combination exists.
1469 */
1470 if ((rtld_flags & RT_FL_DIRCFG) &&
1471 ((dobj == NULL) || (dobj->co_id != 0))) {
1472 Rtc_obj *fobj;
1473 const char *aname = NULL;
1474
1475 /*
1476 * If this object descriptor has not yet been searched for in
1477 * the configuration file go find it.
1478 */
1479 if (dobj == NULL) {
1480 dobj = elf_config_ent(pdp->pd_pname,
1481 (Word)elf_hash(pdp->pd_pname), 0, 0);
1482 if (dobj == NULL)
1483 dobj = &Obj;
1484 pdp->pd_info = (void *)dobj;
1485
1486 if ((dobj->co_flags & (RTC_OBJ_NOEXIST |
1487 RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1488 return (0);
1489 }
1490
1491 /*
1492 * If we found a directory search for the file.
1493 */
1494 if (dobj->co_id != 0) {
1495 if (*strhash == 0)
1496 *strhash = (Word)elf_hash(oname);
1497 fobj = elf_config_ent(oname, *strhash,
1498 dobj->co_id, &aname);
1499
1500 /*
1501 * If this object specifically does not exist, or the
1502 * object can't be found in a know-all-entries
1503 * directory, continue looking. If the object does
1504 * exist determine if an alternative object exists.
1505 */
1506 if (fobj == NULL) {
1507 if (dobj->co_flags & RTC_OBJ_ALLENTS)
1508 return (0);
1509 } else {
1510 if ((fobj->co_flags & (RTC_OBJ_NOEXIST |
1511 RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1512 return (0);
1513
1514 if ((fobj->co_flags & RTC_OBJ_ALTER) &&
1515 (rtld_flags & RT_FL_OBJALT) &&
1516 (lml == &lml_main)) {
1517 int ret;
1518
1519 fdp->fd_flags |= FLG_FD_ALTER;
1520 fdp->fd_nname = aname;
1521
1522 /*
1523 * Attempt to open the alternative path.
1524 * If this fails, and the alternative is
1525 * flagged as optional, fall through to
1526 * open the original path.
1527 */
1528 ret = _find_file(lml, clmp, flags, fdp,
1529 rej, pdp, 1, in_nfavl);
1530 if (ret || ((fobj->co_flags &
1531 RTC_OBJ_OPTINAL) == 0))
1532 return (ret);
1533
1534 fdp->fd_flags &= ~FLG_FD_ALTER;
1535 }
1536 }
1537 }
1538 }
1539
1540 /*
1541 * Protect ourselves from building an invalid pathname.
1542 */
1543 if ((olen + pdp->pd_plen + 1) >= PATH_MAX) {
1544 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), oname,
1545 strerror(ENAMETOOLONG));
1546 return (0);
1547 }
1548 if ((fdp->fd_nname = (LM_GET_SO(clmp)(pdp->pd_pname, oname,
1549 pdp->pd_plen, olen))) == NULL)
1550 return (0);
1551
1552 return (_find_file(lml, clmp, flags, fdp, rej, pdp, 0, in_nfavl));
1553 }
1554
1555 static Fct *Vector[] = {
1556 &elf_fct,
1557 0
1558 };
1559
1560 /*
1561 * Remap the first page of a file to provide a better diagnostic as to why
1562 * an mmapobj(2) operation on this file failed. Sadly, mmapobj(), and all
1563 * system calls for that matter, only pass back a generic failure in errno.
1564 * Hopefully one day this will be improved, but in the mean time we repeat
1565 * the kernels ELF verification to try and provide more detailed information.
1566 */
1567 static int
map_fail(Fdesc * fdp,size_t fsize,const char * name,int fd,Rej_desc * rej)1568 map_fail(Fdesc *fdp, size_t fsize, const char *name, int fd, Rej_desc *rej)
1569 {
1570 caddr_t addr;
1571 int vnum;
1572 size_t size;
1573
1574 /*
1575 * Use the original file size to determine what to map, and catch the
1576 * obvious error of a zero sized file.
1577 */
1578 if (fsize == 0) {
1579 rej->rej_type = SGS_REJ_UNKFILE;
1580 return (1);
1581 } else if (fsize < syspagsz)
1582 size = fsize;
1583 else
1584 size = syspagsz;
1585
1586 if ((addr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
1587 return (0);
1588
1589 rej->rej_type = 0;
1590
1591 /*
1592 * Validate the file against each supported file type. Should a
1593 * characteristic of the file be found invalid for this platform, a
1594 * rejection message will have been recorded.
1595 */
1596 for (vnum = 0; Vector[vnum]; vnum++) {
1597 if (((Vector[vnum]->fct_verify_file)(addr, size,
1598 fdp, name, rej) == 0) && rej->rej_type)
1599 break;
1600 }
1601
1602 /*
1603 * If no rejection message has been recorded, then this is simply an
1604 * unknown file type.
1605 */
1606 if (rej->rej_type == 0)
1607 rej->rej_type = SGS_REJ_UNKFILE;
1608
1609 (void) munmap(addr, size);
1610 return (1);
1611 }
1612
1613 /*
1614 * Unmap a file.
1615 */
1616 void
unmap_obj(mmapobj_result_t * mpp,uint_t mapnum)1617 unmap_obj(mmapobj_result_t *mpp, uint_t mapnum)
1618 {
1619 uint_t num;
1620
1621 for (num = 0; num < mapnum; num++) {
1622 /* LINTED */
1623 (void) munmap((void *)(uintptr_t)mpp[num].mr_addr,
1624 mpp[num].mr_msize);
1625 }
1626 cnt_unmap++;
1627 }
1628
1629 /*
1630 * Map a file.
1631 */
1632 Fct *
map_obj(Lm_list * lml,Fdesc * fdp,size_t fsize,const char * name,int fd,Rej_desc * rej)1633 map_obj(Lm_list *lml, Fdesc *fdp, size_t fsize, const char *name, int fd,
1634 Rej_desc *rej)
1635 {
1636 static mmapobj_result_t *smpp = NULL;
1637 static uint_t smapnum;
1638 mmapobj_result_t *mpp;
1639 uint_t mnum, mapnum, mflags;
1640 void *padding;
1641
1642 /*
1643 * Allocate an initial mapping array. The initial size should be large
1644 * enough to handle the normal ELF objects we come across.
1645 */
1646 if (smpp == NULL) {
1647 smpp = malloc(sizeof (mmapobj_result_t) * MMAPFD_NUM);
1648 if (smpp == NULL)
1649 return (NULL);
1650 smapnum = MMAPFD_NUM;
1651 }
1652
1653 /*
1654 * If object padding is required, set the necessary flags.
1655 */
1656 if (r_debug.rtd_objpad) {
1657 mflags = MMOBJ_INTERPRET | MMOBJ_PADDING;
1658 padding = &r_debug.rtd_objpad;
1659 } else {
1660 mflags = MMOBJ_INTERPRET;
1661 padding = NULL;
1662 }
1663
1664 /*
1665 * Map the file. If the number of mappings required by this file
1666 * exceeds the present mapping structure, an error indicating the
1667 * return data is too big is returned. Bail on any other error.
1668 */
1669 mapnum = smapnum;
1670 if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) {
1671 if (errno != E2BIG) {
1672 int err = errno;
1673
1674 /*
1675 * An unsupported error indicates that there's something
1676 * incompatible with this ELF file, and the process that
1677 * is already running. Map the first page of the file
1678 * and see if we can generate a better error message.
1679 */
1680 if ((errno == ENOTSUP) && map_fail(fdp, fsize, name,
1681 fd, rej))
1682 return (NULL);
1683
1684 rej->rej_type = SGS_REJ_STR;
1685 rej->rej_str = strerror(err);
1686 return (NULL);
1687 }
1688
1689 /*
1690 * The mapping requirement exceeds the present mapping
1691 * structure, however the number of mapping required is
1692 * available in the mapping number.
1693 */
1694 free((void *)smpp);
1695 if ((smpp = malloc(sizeof (mmapobj_result_t) * mapnum)) == NULL)
1696 return (NULL);
1697 smapnum = mapnum;
1698
1699 /*
1700 * With the appropriate mapping structure, try the mapping
1701 * request again.
1702 */
1703 if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) {
1704 rej->rej_type = SGS_REJ_STR;
1705 rej->rej_str = strerror(errno);
1706 return (NULL);
1707 }
1708 }
1709 ASSERT(mapnum != 0);
1710
1711 /*
1712 * Traverse the mappings in search of a file type ld.so.1 can process.
1713 * If the file type is verified as one ld.so.1 can process, retain the
1714 * mapping information, and the number of mappings this object uses,
1715 * and clear the static mapping pointer for the next map_obj() use of
1716 * mmapobj().
1717 */
1718 DBG_CALL(Dbg_file_mmapobj(lml, name, smpp, mapnum));
1719 cnt_map++;
1720
1721 for (mnum = 0, mpp = smpp; mnum < mapnum; mnum++, mpp++) {
1722 uint_t flags = (mpp->mr_flags & MR_TYPE_MASK);
1723 Fct *fptr = NULL;
1724
1725 if (flags == MR_HDR_ELF) {
1726 fptr = elf_verify((mpp->mr_addr + mpp->mr_offset),
1727 mpp->mr_fsize, fdp, name, rej);
1728 }
1729 if (fptr) {
1730 fdp->fd_mapn = mapnum;
1731 fdp->fd_mapp = smpp;
1732
1733 smpp = NULL;
1734
1735 return (fptr);
1736 }
1737 }
1738
1739 /*
1740 * If the mapped file is inappropriate, indicate that the file type is
1741 * unknown, and free the mapping.
1742 */
1743 if (rej->rej_type == 0)
1744 rej->rej_type = SGS_REJ_UNKFILE;
1745 unmap_obj(smpp, mapnum);
1746
1747 return (NULL);
1748 }
1749
1750 /*
1751 * A unique file has been opened. Create a link-map to represent it, and
1752 * process the various names by which it can be referenced.
1753 */
1754 Rt_map *
load_file(Lm_list * lml,Aliste lmco,Rt_map * clmp,Fdesc * fdp,int * in_nfavl)1755 load_file(Lm_list *lml, Aliste lmco, Rt_map *clmp, Fdesc *fdp, int *in_nfavl)
1756 {
1757 mmapobj_result_t *fpmpp = NULL, *fmpp = NULL, *lpmpp, *lmpp;
1758 mmapobj_result_t *hmpp, *mpp, *ompp = fdp->fd_mapp;
1759 uint_t mnum, omapnum = fdp->fd_mapn;
1760 const char *nname = fdp->fd_nname;
1761 Rt_map *nlmp;
1762 Ehdr *ehdr = NULL;
1763
1764 /*
1765 * Traverse the mappings for the input file to capture generic mapping
1766 * information, and create a link-map to represent the file.
1767 */
1768 for (mnum = 0, mpp = ompp; mnum < omapnum; mnum++, mpp++) {
1769 uint_t flags = (mpp->mr_flags & MR_TYPE_MASK);
1770
1771 /*
1772 * Keep track of the first and last mappings that may include
1773 * padding.
1774 */
1775 if (fpmpp == NULL)
1776 fpmpp = mpp;
1777 lpmpp = mpp;
1778
1779 /*
1780 * Keep track of the first and last mappings that do not include
1781 * padding.
1782 */
1783 if (flags != MR_PADDING) {
1784 if (fmpp == NULL)
1785 fmpp = mpp;
1786 lmpp = mpp;
1787 }
1788 if (flags == MR_HDR_ELF) {
1789 /* LINTED */
1790 ehdr = (Ehdr *)(mpp->mr_addr + mpp->mr_offset);
1791 hmpp = mpp;
1792 }
1793 }
1794
1795 /*
1796 * The only ELF files we can handle are ET_EXEC, ET_DYN, and ET_REL.
1797 *
1798 * ET_REL must be processed by ld(1) to create an in-memory ET_DYN.
1799 * The initial processing carried out by elf_obj_file() creates a
1800 * temporary link-map, that acts as a place holder, until the objects
1801 * processing is finished with elf_obj_fini().
1802 */
1803 if (ehdr && (ehdr->e_type == ET_REL)) {
1804 if ((nlmp = elf_obj_file(lml, lmco, clmp, nname, hmpp, ompp,
1805 omapnum)) == NULL)
1806 return (nlmp);
1807 } else {
1808 Addr addr;
1809 size_t msize;
1810
1811 /*
1812 * The size of the total reservation, and the padding range,
1813 * are a historic artifact required by debuggers. Although
1814 * these values express the range of the associated mappings,
1815 * there can be holes between segments (in which small objects
1816 * could be mapped). Anyone who needs to verify offsets
1817 * against segments should analyze all the object mappings,
1818 * rather than relying on these address ranges.
1819 */
1820 addr = (Addr)(hmpp->mr_addr + hmpp->mr_offset);
1821 msize = lmpp->mr_addr + lmpp->mr_msize - fmpp->mr_addr;
1822
1823 if ((nlmp = ((fdp->fd_ftp)->fct_new_lmp)(lml, lmco, fdp, addr,
1824 msize, NULL, clmp, in_nfavl)) == NULL)
1825 return (NULL);
1826
1827 /*
1828 * Save generic mapping information.
1829 */
1830 MMAPS(nlmp) = ompp;
1831 MMAPCNT(nlmp) = omapnum;
1832 PADSTART(nlmp) = (ulong_t)fpmpp->mr_addr;
1833 PADIMLEN(nlmp) = lpmpp->mr_addr + lpmpp->mr_msize -
1834 fpmpp->mr_addr;
1835 }
1836
1837 /*
1838 * Save the dev/inode information for later comparisons, and identify
1839 * this as a new object.
1840 */
1841 STDEV(nlmp) = fdp->fd_dev;
1842 STINO(nlmp) = fdp->fd_ino;
1843 FLAGS(nlmp) |= FLG_RT_NEWLOAD;
1844
1845 /*
1846 * If this is ELF relocatable object, we're done for now.
1847 */
1848 if (ehdr && (ehdr->e_type == ET_REL))
1849 return (nlmp);
1850
1851 /*
1852 * Insert the names of this link-map into the FullPathNode AVL tree.
1853 * Save both the NAME() and PATHNAME() if the names differ.
1854 */
1855 (void) fullpath(nlmp, fdp);
1856
1857 if ((NAME(nlmp)[0] == '/') && (fpavl_insert(lml, nlmp, NAME(nlmp),
1858 fdp->fd_avlwhere) == 0)) {
1859 remove_so(lml, nlmp, clmp);
1860 return (NULL);
1861 }
1862 if (((NAME(nlmp)[0] != '/') || (NAME(nlmp) != PATHNAME(nlmp))) &&
1863 (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)) {
1864 remove_so(lml, nlmp, clmp);
1865 return (NULL);
1866 }
1867
1868 /*
1869 * If this is a secure application, record any full path name directory
1870 * in which this dependency has been found. This directory can be
1871 * deemed safe (as we've already found a dependency here). This
1872 * recording provides a fall-back should another objects $ORIGIN
1873 * definition expands to this directory, an expansion that would
1874 * ordinarily be deemed insecure.
1875 */
1876 if (rtld_flags & RT_FL_SECURE) {
1877 if (NAME(nlmp)[0] == '/')
1878 spavl_insert(NAME(nlmp));
1879 if ((NAME(nlmp) != PATHNAME(nlmp)) &&
1880 (PATHNAME(nlmp)[0] == '/'))
1881 spavl_insert(PATHNAME(nlmp));
1882 }
1883
1884 /*
1885 * If we're processing an alternative object reset the original name
1886 * for possible $ORIGIN processing.
1887 */
1888 if (fdp->fd_flags & FLG_FD_ALTER) {
1889 const char *odir, *ndir;
1890 size_t olen;
1891
1892 FLAGS(nlmp) |= FLG_RT_ALTER;
1893
1894 /*
1895 * If we were given a pathname containing a slash then the
1896 * original name is still in oname. Otherwise the original
1897 * directory is in dir->p_name (which is all we need for
1898 * $ORIGIN).
1899 */
1900 if (fdp->fd_flags & FLG_FD_SLASH) {
1901 char *ofil;
1902
1903 odir = fdp->fd_oname;
1904 ofil = strrchr(fdp->fd_oname, '/');
1905 olen = ofil - odir + 1;
1906 } else {
1907 odir = fdp->fd_odir;
1908 olen = strlen(odir) + 1;
1909 }
1910 if ((ndir = stravl_insert(odir, 0, olen, 1)) == NULL) {
1911 remove_so(lml, nlmp, clmp);
1912 return (NULL);
1913 }
1914 ORIGNAME(nlmp) = ndir;
1915 DIRSZ(nlmp) = --olen;
1916 }
1917
1918 return (nlmp);
1919 }
1920
1921 /*
1922 * This function loads the named file and returns a pointer to its link map.
1923 * It is assumed that the caller has already checked that the file is not
1924 * already loaded before calling this function (refer is_so_loaded()).
1925 * Find and open the file, map it into memory, add it to the end of the list
1926 * of link maps and return a pointer to the new link map. Return 0 on error.
1927 */
1928 static Rt_map *
load_so(Lm_list * lml,Aliste lmco,Rt_map * clmp,uint_t flags,Fdesc * fdp,Rej_desc * rej,int * in_nfavl)1929 load_so(Lm_list *lml, Aliste lmco, Rt_map *clmp, uint_t flags,
1930 Fdesc *fdp, Rej_desc *rej, int *in_nfavl)
1931 {
1932 const char *oname = fdp->fd_oname;
1933 Pdesc *pdp;
1934
1935 /*
1936 * If this path name hasn't already been identified as containing a
1937 * slash, check the path name. Most paths have been constructed
1938 * through appending a file name to a search path, and/or have been
1939 * inspected by expand(), and thus have a slash. However, we can
1940 * receive path names via auditors or configuration files, and thus
1941 * an evaluation here catches these instances.
1942 */
1943 if ((fdp->fd_flags & FLG_FD_SLASH) == 0) {
1944 const char *str;
1945
1946 for (str = oname; *str; str++) {
1947 if (*str == '/') {
1948 fdp->fd_flags |= FLG_FD_SLASH;
1949 break;
1950 }
1951 }
1952 }
1953
1954 /*
1955 * If we are passed a 'null' link-map this means that this is the first
1956 * object to be loaded on this link-map list. In that case we set the
1957 * link-map to ld.so.1's link-map.
1958 *
1959 * This link-map is referenced to determine what lookup rules to use
1960 * when searching for files. By using ld.so.1's we are defaulting to
1961 * ELF look-up rules.
1962 *
1963 * Note: This case happens when loading the first object onto
1964 * the plt_tracing link-map.
1965 */
1966 if (clmp == 0)
1967 clmp = lml_rtld.lm_head;
1968
1969 /*
1970 * If this path resulted from a $CAPABILITY specification, then the
1971 * best capability object has already been establish, and is available
1972 * in the calling file descriptor. Perform some minor book-keeping so
1973 * that we can fall through into common code.
1974 */
1975 if (flags & FLG_RT_CAP) {
1976 /*
1977 * If this object is already loaded, we're done.
1978 */
1979 if (fdp->fd_lmp)
1980 return (fdp->fd_lmp);
1981
1982 /*
1983 * Obtain the avl index for this object.
1984 */
1985 (void) fpavl_recorded(lml, fdp->fd_nname, 0,
1986 &(fdp->fd_avlwhere));
1987
1988 } else if (fdp->fd_flags & FLG_FD_SLASH) {
1989 Rej_desc _rej = { 0 };
1990
1991 if (find_path(lml, clmp, flags, fdp, &_rej, in_nfavl) == 0) {
1992 rejection_inherit(rej, &_rej);
1993 return (NULL);
1994 }
1995
1996 /*
1997 * If this object is already loaded, we're done.
1998 */
1999 if (fdp->fd_lmp)
2000 return (fdp->fd_lmp);
2001
2002 } else {
2003 /*
2004 * No '/' - for each directory on list, make a pathname using
2005 * that directory and filename and try to open that file.
2006 */
2007 Spath_desc sd = { search_rules, NULL, 0 };
2008 Word strhash = 0;
2009 int found = 0;
2010
2011 /*
2012 * Traverse the search path lists, creating full pathnames and
2013 * attempt to load each path.
2014 */
2015 for (pdp = get_next_dir(&sd, clmp, flags); pdp;
2016 pdp = get_next_dir(&sd, clmp, flags)) {
2017 Rej_desc _rej = { 0 };
2018 Fdesc fd = { 0 };
2019
2020 /*
2021 * Under debugging, duplicate path name entries are
2022 * tagged but remain part of the search path list so
2023 * that they can be diagnosed under "unused" processing.
2024 * Skip these entries, as this path would have already
2025 * been attempted.
2026 */
2027 if (pdp->pd_flags & PD_FLG_DUPLICAT)
2028 continue;
2029
2030 fd = *fdp;
2031
2032 /*
2033 * Try and locate this file. Make sure to clean up
2034 * any rejection information should the file have
2035 * been found, but not appropriate.
2036 */
2037 if (find_file(lml, clmp, flags, &fd, &_rej, pdp,
2038 &strhash, in_nfavl) == 0) {
2039 rejection_inherit(rej, &_rej);
2040 continue;
2041 }
2042
2043 /*
2044 * Indicate that this search path has been used. If
2045 * this is an LD_LIBRARY_PATH setting, ignore any use
2046 * by ld.so.1 itself.
2047 */
2048 if (((pdp->pd_flags & LA_SER_LIBPATH) == 0) ||
2049 ((lml->lm_flags & LML_FLG_RTLDLM) == 0))
2050 pdp->pd_flags |= PD_FLG_USED;
2051
2052 /*
2053 * If this object is already loaded, we're done.
2054 */
2055 *fdp = fd;
2056 if (fdp->fd_lmp)
2057 return (fdp->fd_lmp);
2058
2059 fdp->fd_odir = pdp->pd_pname;
2060 found = 1;
2061 break;
2062 }
2063
2064 /*
2065 * If the file couldn't be loaded, do another comparison of
2066 * loaded files using just the basename. This catches folks
2067 * who may have loaded multiple full pathname files (possibly
2068 * from setxid applications) to satisfy dependency relationships
2069 * (i.e., a file might have a dependency on foo.so.1 which has
2070 * already been opened using its full pathname).
2071 */
2072 if (found == 0)
2073 return (is_so_loaded(lml, oname, in_nfavl));
2074 }
2075
2076 /*
2077 * Trace that this successfully opened file is about to be processed.
2078 * Note, as part of processing a family of hardware capabilities filtees
2079 * a number of candidates may have been opened and mapped to determine
2080 * their capability requirements. At this point we've decided which
2081 * of the candidates to use.
2082 */
2083 if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
2084 trace_so(clmp, 0, fdp->fd_oname, fdp->fd_nname,
2085 (fdp->fd_flags & FLG_FD_ALTER), 0);
2086 }
2087
2088 /*
2089 * Finish mapping the file and return the link-map descriptor.
2090 */
2091 return (load_file(lml, lmco, clmp, fdp, in_nfavl));
2092 }
2093
2094 /*
2095 * Trace an attempt to load an object, and seed the originating name.
2096 */
2097 const char *
load_trace(Lm_list * lml,Pdesc * pdp,Rt_map * clmp,Fdesc * fdp)2098 load_trace(Lm_list *lml, Pdesc *pdp, Rt_map *clmp, Fdesc *fdp)
2099 {
2100 const char *name = pdp->pd_pname;
2101
2102 DBG_CALL(Dbg_libs_find(lml, name));
2103
2104 /*
2105 * First generate any ldd(1) diagnostics.
2106 */
2107 if ((lml->lm_flags & (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_SEARCH)) &&
2108 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0))
2109 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, NAME(clmp));
2110
2111 /*
2112 * Propagate any knowledge of a slash within the path name.
2113 */
2114 if (pdp->pd_flags & PD_FLG_PNSLASH)
2115 fdp->fd_flags |= FLG_FD_SLASH;
2116
2117 /*
2118 * If we're being audited tell any audit libraries of the file we're
2119 * about to go search for.
2120 */
2121 if (aud_activity ||
2122 ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_ACTIVITY))
2123 audit_activity(clmp, LA_ACT_ADD);
2124
2125 if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
2126 char *aname;
2127
2128 /*
2129 * The auditor can indicate that this object should be ignored.
2130 */
2131 if ((aname =
2132 audit_objsearch(clmp, name, LA_SER_ORIG)) == NULL) {
2133 DBG_CALL(Dbg_audit_terminate(lml, name));
2134 return (NULL);
2135 }
2136
2137 if (name != aname) {
2138 fdp->fd_flags &= ~FLG_FD_SLASH;
2139 name = aname;
2140 }
2141 }
2142 fdp->fd_oname = name;
2143 return (name);
2144 }
2145
2146 /*
2147 * Having loaded an object and created a link-map to describe it, finish
2148 * processing this stage, including verifying any versioning requirements,
2149 * updating the objects mode, creating a handle if necessary, and adding this
2150 * object to existing handles if required.
2151 */
2152 static int
load_finish(Lm_list * lml,const char * name,Rt_map * clmp,int nmode,uint_t flags,Grp_hdl ** hdl,Rt_map * nlmp)2153 load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,
2154 uint_t flags, Grp_hdl **hdl, Rt_map *nlmp)
2155 {
2156 Aliste idx1;
2157 Grp_hdl *ghp;
2158 int promote;
2159 uint_t rdflags;
2160
2161 /*
2162 * If this dependency is associated with a required version ensure that
2163 * the version is present in the loaded file.
2164 */
2165 if (((rtld_flags & RT_FL_NOVERSION) == 0) && THIS_IS_ELF(clmp) &&
2166 VERNEED(clmp) && (elf_verify_vers(name, clmp, nlmp) == 0))
2167 return (0);
2168
2169 /*
2170 * If this object has indicated that it should be isolated as a group
2171 * (DT_FLAGS_1 contains DF_1_GROUP - object was built with -B group),
2172 * or if the callers direct bindings indicate it should be isolated as
2173 * a group (DYNINFO flags contains FLG_DI_GROUP - dependency following
2174 * -zgroupperm), establish the appropriate mode.
2175 *
2176 * The intent of an object defining itself as a group is to isolate the
2177 * relocation of the group within its own members, however, unless
2178 * opened through dlopen(), in which case we assume dlsym() will be used
2179 * to locate symbols in the new object, we still need to associate the
2180 * new object with the caller so that the caller can bind to this new
2181 * object. This is equivalent to a dlopen(RTLD_GROUP) and dlsym()
2182 * using the returned handle.
2183 */
2184 if ((FLAGS(nlmp) | flags) & FLG_RT_SETGROUP) {
2185 nmode &= ~RTLD_WORLD;
2186 nmode |= RTLD_GROUP;
2187
2188 /*
2189 * If the object wasn't explicitly dlopen()'ed, in which case a
2190 * handle would have been requested, associate the object with
2191 * the parent.
2192 */
2193 if ((flags & FLG_RT_PUBHDL) == 0)
2194 nmode |= RTLD_PARENT;
2195 }
2196
2197 /*
2198 * Establish new mode and flags.
2199 */
2200 promote = update_mode(nlmp, MODE(nlmp), nmode);
2201 FLAGS(nlmp) |= flags;
2202
2203 /*
2204 * Establish the flags for any referenced dependency descriptors
2205 * (Grp_desc).
2206 *
2207 * - The referenced object is available for dlsym().
2208 * - The referenced object is available to relocate against.
2209 * - The referenced object should have it's dependencies
2210 * added to this handle
2211 */
2212 rdflags = (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS);
2213
2214 /*
2215 * If we've been asked to establish a handle create one for this object.
2216 * Or, if this object has already been analyzed, but this reference
2217 * requires that the mode of the object be promoted, create a private
2218 * handle to propagate the new modes to all this objects dependencies.
2219 */
2220 if ((FLAGS(nlmp) & (FLG_RT_PUBHDL | FLG_RT_PRIHDL)) ||
2221 (promote && (FLAGS(nlmp) & FLG_RT_ANALYZED))) {
2222 uint_t oflags, hflags, cdflags = 0;
2223
2224 /*
2225 * Establish any flags for the handle (Grp_hdl).
2226 *
2227 * - Public handles establish dependencies between objects
2228 * that must be taken into account when dlclose()'ing
2229 * objects. Private handles provide for collecting
2230 * dependencies, but do not affect dlclose(). Note that
2231 * a handle may already exist, but the public/private
2232 * state is set to trigger the required propagation of the
2233 * handle's flags and any dependency gathering.
2234 * - Use of the RTLD_FIRST flag indicates that only the first
2235 * dependency on the handle (the new object) can be used
2236 * to satisfy dlsym() requests.
2237 */
2238 if (FLAGS(nlmp) & FLG_RT_PUBHDL)
2239 hflags = GPH_PUBLIC;
2240 else
2241 hflags = GPH_PRIVATE;
2242
2243 if (nmode & RTLD_FIRST)
2244 hflags |= GPH_FIRST;
2245
2246 /*
2247 * Establish the flags for this callers dependency descriptor
2248 * (Grp_desc).
2249 *
2250 * - The creation of a public handle creates a descriptor
2251 * for the referenced object and the caller (parent).
2252 * Typically, the handle is created for dlopen() or for
2253 * filtering. A private handle does not need to maintain
2254 * a descriptor to the parent.
2255 * - Use of the RTLD_PARENT flag indicates that the parent
2256 * can be relocated against.
2257 */
2258 if (FLAGS(nlmp) & FLG_RT_PUBHDL) {
2259 cdflags |= GPD_PARENT;
2260 if (nmode & RTLD_PARENT)
2261 cdflags |= GPD_RELOC;
2262 }
2263
2264 /*
2265 * Now that the handle flags have been established, remove any
2266 * handle definition from the referenced object so that the
2267 * definitions don't mistakenly get inherited by a dependency.
2268 */
2269 oflags = FLAGS(nlmp);
2270 FLAGS(nlmp) &= ~(FLG_RT_PUBHDL | FLG_RT_PRIHDL);
2271
2272 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD));
2273 if ((ghp = hdl_create(lml, nlmp, clmp, hflags, rdflags,
2274 cdflags)) == NULL)
2275 return (0);
2276
2277 /*
2278 * Add any dependencies that are already loaded, to the handle.
2279 */
2280 if (hdl_initialize(ghp, nlmp, nmode, promote) == 0)
2281 return (0);
2282
2283 if (hdl)
2284 *hdl = ghp;
2285
2286 /*
2287 * If we were asked to create a public handle, we're done.
2288 *
2289 * If this is a private handle request, then the handle is left
2290 * intact with a GPH_PRIVATE identifier. This handle is a
2291 * convenience for processing the dependencies of this object,
2292 * but does not affect how this object might be dlclose()'d.
2293 * For a private handle, fall through to carry out any group
2294 * processing.
2295 */
2296 if (oflags & FLG_RT_PUBHDL)
2297 return (1);
2298 }
2299
2300 /*
2301 * If the caller isn't part of a group we're done.
2302 */
2303 if (GROUPS(clmp) == NULL)
2304 return (1);
2305
2306 /*
2307 * Determine if our caller is already associated with a handle, if so
2308 * we need to add this object to any handles that already exist.
2309 * Traverse the list of groups our caller is a member of and add this
2310 * new link-map to those groups.
2311 */
2312 for (APLIST_TRAVERSE(GROUPS(clmp), idx1, ghp)) {
2313 Aliste idx2;
2314 Grp_desc *gdp;
2315 int ale;
2316 Rt_map *dlmp1;
2317 APlist *lmalp = NULL;
2318
2319 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD));
2320
2321 /*
2322 * If the caller doesn't indicate that its dependencies should
2323 * be added to a handle, ignore it. This case identifies a
2324 * parent of a dlopen(RTLD_PARENT) request.
2325 */
2326 for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
2327 if (gdp->gd_depend == clmp)
2328 break;
2329 }
2330 if ((gdp->gd_flags & GPD_ADDEPS) == 0)
2331 continue;
2332
2333 if ((gdp = hdl_add(ghp, nlmp, rdflags, &ale)) == NULL)
2334 return (0);
2335
2336 /*
2337 * If this member already exists then its dependencies will
2338 * have already been processed.
2339 */
2340 if (ale == ALE_EXISTS)
2341 continue;
2342
2343 /*
2344 * If the object we've added has just been opened, it will not
2345 * yet have been processed for its dependencies, these will be
2346 * added on later calls to load_one(). If it doesn't have any
2347 * dependencies we're also done.
2348 */
2349 if (((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) ||
2350 (DEPENDS(nlmp) == NULL))
2351 continue;
2352
2353 /*
2354 * Otherwise, this object exists and has dependencies, so add
2355 * all of its dependencies to the handle were operating on.
2356 */
2357 if (aplist_append(&lmalp, nlmp, AL_CNT_DEPCLCT) == NULL)
2358 return (0);
2359
2360 for (APLIST_TRAVERSE(lmalp, idx2, dlmp1)) {
2361 Aliste idx3;
2362 Bnd_desc *bdp;
2363
2364 /*
2365 * Add any dependencies of this dependency to the
2366 * dynamic dependency list so they can be further
2367 * processed.
2368 */
2369 for (APLIST_TRAVERSE(DEPENDS(dlmp1), idx3, bdp)) {
2370 Rt_map *dlmp2 = bdp->b_depend;
2371
2372 if ((bdp->b_flags & BND_NEEDED) == 0)
2373 continue;
2374
2375 if (aplist_test(&lmalp, dlmp2,
2376 AL_CNT_DEPCLCT) == 0) {
2377 free(lmalp);
2378 return (0);
2379 }
2380 }
2381
2382 if (nlmp == dlmp1)
2383 continue;
2384
2385 if ((gdp =
2386 hdl_add(ghp, dlmp1, rdflags, &ale)) == NULL) {
2387 free(lmalp);
2388 return (0);
2389 }
2390
2391 if (ale == ALE_CREATE)
2392 (void) update_mode(dlmp1, MODE(dlmp1), nmode);
2393 }
2394 free(lmalp);
2395 }
2396 return (1);
2397 }
2398
2399 /*
2400 * The central routine for loading shared objects. Insures ldd() diagnostics,
2401 * handle creation, and any other related additions are all done in one place.
2402 */
2403 Rt_map *
load_path(Lm_list * lml,Aliste lmco,Rt_map * clmp,int nmode,uint_t flags,Grp_hdl ** hdl,Fdesc * fdp,Rej_desc * rej,int * in_nfavl)2404 load_path(Lm_list *lml, Aliste lmco, Rt_map *clmp, int nmode, uint_t flags,
2405 Grp_hdl **hdl, Fdesc *fdp, Rej_desc *rej, int *in_nfavl)
2406 {
2407 const char *name = fdp->fd_oname;
2408 Rt_map *nlmp;
2409
2410 if ((nmode & RTLD_NOLOAD) == 0) {
2411 int oin_nfavl;
2412
2413 /*
2414 * Keep track of the number of not-found loads.
2415 */
2416 if (in_nfavl)
2417 oin_nfavl = *in_nfavl;
2418
2419 /*
2420 * If this isn't a noload request attempt to load the file.
2421 */
2422 if ((nlmp = load_so(lml, lmco, clmp, flags, fdp, rej,
2423 in_nfavl)) == NULL)
2424 return (NULL);
2425
2426 /*
2427 * If this file has been found, reset the not-found load count.
2428 * Although a search for this file might have inspected a number
2429 * of non-existent path names, the file has been found so there
2430 * is no need to accumulate a non-found count, as this may
2431 * trigger unnecessary fall back (retry) processing.
2432 */
2433 if (in_nfavl)
2434 *in_nfavl = oin_nfavl;
2435
2436 /*
2437 * If we've loaded a library which identifies itself as not
2438 * being dlopen()'able catch it here. Let non-dlopen()'able
2439 * objects through under RTLD_CONFGEN as they're only being
2440 * mapped to be dldump()'ed.
2441 */
2442 if ((rtld_flags & RT_FL_APPLIC) && ((FLAGS(nlmp) &
2443 (FLG_RT_NOOPEN | FLG_RT_RELOCED)) == FLG_RT_NOOPEN) &&
2444 ((nmode & RTLD_CONFGEN) == 0)) {
2445 Rej_desc _rej = { 0 };
2446
2447 _rej.rej_name = name;
2448 _rej.rej_type = SGS_REJ_STR;
2449 _rej.rej_str = MSG_INTL(MSG_GEN_NOOPEN);
2450 DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH));
2451 rejection_inherit(rej, &_rej);
2452 remove_so(lml, nlmp, clmp);
2453 return (NULL);
2454 }
2455 } else {
2456 /*
2457 * If it's a NOLOAD request - check to see if the object
2458 * has already been loaded.
2459 */
2460 nlmp = is_so_loaded(lml, name, in_nfavl);
2461 if (nlmp != NULL) {
2462 if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) &&
2463 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
2464 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name,
2465 NAME(clmp));
2466 /* BEGIN CSTYLED */
2467 if (*name == '/')
2468 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH),
2469 name, MSG_ORIG(MSG_STR_EMPTY),
2470 MSG_ORIG(MSG_STR_EMPTY));
2471 else
2472 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV),
2473 name, NAME(nlmp),
2474 MSG_ORIG(MSG_STR_EMPTY),
2475 MSG_ORIG(MSG_STR_EMPTY));
2476 /* END CSTYLED */
2477 }
2478 } else {
2479 Rej_desc _rej = { 0 };
2480
2481 _rej.rej_name = name;
2482 _rej.rej_type = SGS_REJ_STR;
2483 _rej.rej_str = strerror(ENOENT);
2484 DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH));
2485 rejection_inherit(rej, &_rej);
2486 return (NULL);
2487 }
2488 }
2489
2490 /*
2491 * Finish processing this loaded object.
2492 */
2493 if (load_finish(lml, name, clmp, nmode, flags, hdl, nlmp) == 0) {
2494 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD;
2495
2496 /*
2497 * If this object has already been analyzed, then it is in use,
2498 * so even though this operation has failed, it should not be
2499 * torn down.
2500 */
2501 if ((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0)
2502 remove_so(lml, nlmp, clmp);
2503 return (NULL);
2504 }
2505
2506 /*
2507 * If this object is new, and we're being audited, tell the audit
2508 * libraries of the file we've just opened. Note, if the new link-map
2509 * requires local auditing of its dependencies we also register its
2510 * opening.
2511 */
2512 if (FLAGS(nlmp) & FLG_RT_NEWLOAD) {
2513 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD;
2514
2515 if ((lml->lm_tflags | AFLAGS(clmp) | AFLAGS(nlmp)) &
2516 LML_TFLG_AUD_MASK) {
2517 if (audit_objopen(clmp, nlmp) == 0) {
2518 remove_so(lml, nlmp, clmp);
2519 return (NULL);
2520 }
2521 }
2522 }
2523 return (nlmp);
2524 }
2525
2526 /*
2527 * Load one object from a possible list of objects. Typically, for requests
2528 * such as NEEDED's, only one object is specified. However, this object could
2529 * be specified using $ISALIST or $CAPABILITY, in which case only the first
2530 * object that can be loaded is used (ie. the best).
2531 */
2532 Rt_map *
load_one(Lm_list * lml,Aliste lmco,Alist * palp,Rt_map * clmp,int mode,uint_t flags,Grp_hdl ** hdl,int * in_nfavl)2533 load_one(Lm_list *lml, Aliste lmco, Alist *palp, Rt_map *clmp, int mode,
2534 uint_t flags, Grp_hdl **hdl, int *in_nfavl)
2535 {
2536 Rej_desc rej = { 0 };
2537 Aliste idx;
2538 Pdesc *pdp;
2539 const char *name;
2540
2541 for (ALIST_TRAVERSE(palp, idx, pdp)) {
2542 Rt_map *lmp = NULL;
2543
2544 /*
2545 * A $CAPABILITY/$HWCAP requirement can expand into a number of
2546 * candidates.
2547 */
2548 if (pdp->pd_flags & PD_TKN_CAP) {
2549 lmp = load_cap(lml, lmco, pdp->pd_pname, clmp,
2550 mode, (flags | FLG_RT_CAP), hdl, &rej, in_nfavl);
2551 } else {
2552 Fdesc fd = { 0 };
2553
2554 /*
2555 * Trace the inspection of this file, determine any
2556 * auditor substitution, and seed the file descriptor
2557 * with the originating name.
2558 */
2559 if (load_trace(lml, pdp, clmp, &fd) == NULL)
2560 continue;
2561
2562 /*
2563 * Locate and load the file.
2564 */
2565 lmp = load_path(lml, lmco, clmp, mode, flags, hdl, &fd,
2566 &rej, in_nfavl);
2567 }
2568 if (lmp)
2569 return (lmp);
2570 }
2571
2572 /*
2573 * If no objects can be found, use the first path name from the Alist
2574 * to provide a diagnostic. If this pathname originated from an
2575 * expanded token, use the original name for any diagnostic output.
2576 */
2577 pdp = alist_item(palp, 0);
2578
2579 if ((name = pdp->pd_oname) == 0)
2580 name = pdp->pd_pname;
2581
2582 file_notfound(lml, name, clmp, flags, &rej);
2583 return (NULL);
2584 }
2585
2586 /*
2587 * Determine whether a symbol is defined as an interposer.
2588 */
2589 int
is_sym_interposer(Rt_map * lmp,Sym * sym)2590 is_sym_interposer(Rt_map *lmp, Sym *sym)
2591 {
2592 Syminfo *sip = SYMINFO(lmp);
2593
2594 if (sip) {
2595 ulong_t ndx;
2596
2597 ndx = (((ulong_t)sym - (ulong_t)SYMTAB(lmp)) / SYMENT(lmp));
2598 /* LINTED */
2599 sip = (Syminfo *)((char *)sip + (ndx * SYMINENT(lmp)));
2600 if (sip->si_flags & SYMINFO_FLG_INTERPOSE)
2601 return (1);
2602 }
2603 return (0);
2604 }
2605
2606 /*
2607 * While processing direct or group bindings, determine whether the object to
2608 * which we've bound can be interposed upon. In this context, copy relocations
2609 * are a form of interposition.
2610 */
2611 static int
lookup_sym_interpose(Slookup * slp,Sresult * srp,uint_t * binfo,int * in_nfavl)2612 lookup_sym_interpose(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
2613 {
2614 Rt_map *lmp, *clmp, *dlmp = srp->sr_dmap;
2615 Sym *osym = srp->sr_sym;
2616 Slookup sl;
2617 Lm_list *lml;
2618
2619 /*
2620 * If we've bound to a copy relocation definition then we need to assign
2621 * this binding to the original copy reference. Fabricate an inter-
2622 * position diagnostic, as this is a legitimate form of interposition.
2623 */
2624 if (osym && (FLAGS1(dlmp) & FL1_RT_COPYTOOK)) {
2625 Rel_copy *rcp;
2626 Aliste idx;
2627
2628 for (ALIST_TRAVERSE(COPY_R(dlmp), idx, rcp)) {
2629 if ((osym == rcp->r_dsym) || (osym->st_value &&
2630 (osym->st_value == rcp->r_dsym->st_value))) {
2631 srp->sr_dmap = rcp->r_rlmp;
2632 srp->sr_sym = rcp->r_rsym;
2633 *binfo |=
2634 (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF);
2635 return (1);
2636 }
2637 }
2638 }
2639
2640 /*
2641 * If a symbol binding has been established, inspect the link-map list
2642 * of the destination object, otherwise use the link-map list of the
2643 * original caller.
2644 */
2645 if (osym)
2646 clmp = dlmp;
2647 else
2648 clmp = slp->sl_cmap;
2649
2650 lml = LIST(clmp);
2651 lmp = lml->lm_head;
2652
2653 /*
2654 * Prior to Solaris 8, external references from an executable that were
2655 * bound to an uninitialized variable (.bss) within a shared object did
2656 * not establish a copy relocation. This was thought to be an
2657 * optimization, to prevent copying zero's to zero's. Typically,
2658 * interposition took its course, with the shared object binding to the
2659 * executables data definition.
2660 *
2661 * This scenario can be broken when this old executable runs against a
2662 * new shared object that is directly bound. With no copy-relocation
2663 * record, ld.so.1 has no data to trigger the normal vectoring of the
2664 * binding to the executable.
2665 *
2666 * Starting with Solaris 8, a DT_FLAGS entry is written to all objects,
2667 * regardless of there being any DF_ flags entries. Therefore, an
2668 * object without this dynamic tag is susceptible to the copy relocation
2669 * issue. If the executable has no DT_FLAGS tag, and contains the same
2670 * .bss symbol definition as has been directly bound to, redirect the
2671 * binding to the executables data definition.
2672 */
2673 if (osym && ((FLAGS1(lmp) & FL1_RT_DTFLAGS) == 0) &&
2674 (FCT(lmp) == &elf_fct) &&
2675 (ELF_ST_TYPE(osym->st_info) != STT_FUNC) &&
2676 are_bits_zero(dlmp, osym, 0)) {
2677 Sresult sr;
2678
2679 /*
2680 * Initialize a local symbol result descriptor, using the
2681 * original symbol name. Initialize a local symbol lookup
2682 * descriptor, using the original lookup information, and a
2683 * new initial link-map.
2684 */
2685 SRESULT_INIT(sr, slp->sl_name);
2686 sl = *slp;
2687 sl.sl_imap = lmp;
2688
2689 /*
2690 * Determine whether the same symbol name exists within the
2691 * executable, that the size and type of symbol are the same,
2692 * and that the symbol is also associated with .bss.
2693 */
2694 if (SYMINTP(lmp)(&sl, &sr, binfo, in_nfavl)) {
2695 Sym *isym = sr.sr_sym;
2696
2697 if ((isym->st_size == osym->st_size) &&
2698 (isym->st_info == osym->st_info) &&
2699 are_bits_zero(lmp, isym, 1)) {
2700 *srp = sr;
2701 *binfo |=
2702 (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF);
2703 return (1);
2704 }
2705 }
2706 }
2707
2708 if ((lml->lm_flags & LML_FLG_INTRPOSE) == 0)
2709 return (0);
2710
2711 /*
2712 * Traverse the list of known interposers to determine whether any
2713 * offer the same symbol. Note, the head of the link-map could be
2714 * identified as an interposer. Otherwise, skip the head of the
2715 * link-map, so that we don't bind to any .plt references, or
2716 * copy-relocation destinations unintentionally.
2717 */
2718 lmp = lml->lm_head;
2719 sl = *slp;
2720
2721 if (((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) || (sl.sl_flags & LKUP_COPY))
2722 lmp = NEXT_RT_MAP(lmp);
2723
2724 for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
2725 if (FLAGS(lmp) & FLG_RT_DELETE)
2726 continue;
2727 if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0)
2728 break;
2729
2730 /*
2731 * If we had already bound to this object, there's no point in
2732 * searching it again, we're done.
2733 */
2734 if (lmp == dlmp)
2735 break;
2736
2737 /*
2738 * If this interposer can be inspected by the caller, look for
2739 * the symbol within the interposer.
2740 */
2741 if (callable(clmp, lmp, 0, sl.sl_flags)) {
2742 Sresult sr;
2743
2744 /*
2745 * Initialize a local symbol result descriptor, using
2746 * the original symbol name. Initialize a local symbol
2747 * lookup descriptor, using the original lookup
2748 * information, and a new initial link-map.
2749 */
2750 SRESULT_INIT(sr, slp->sl_name);
2751 sl.sl_imap = lmp;
2752
2753 if (SYMINTP(lmp)(&sl, &sr, binfo, in_nfavl)) {
2754 Sym *isym = sr.sr_sym;
2755 Rt_map *ilmp = sr.sr_dmap;
2756
2757 /*
2758 * If this object provides individual symbol
2759 * interposers, make sure that the symbol we
2760 * have found is tagged as an interposer.
2761 */
2762 if ((FLAGS(ilmp) & FLG_RT_SYMINTPO) &&
2763 (is_sym_interposer(ilmp, isym) == 0))
2764 continue;
2765
2766 /*
2767 * Indicate this binding has occurred to an
2768 * interposer, and return the symbol.
2769 */
2770 *srp = sr;
2771 *binfo |= DBG_BINFO_INTERPOSE;
2772 return (1);
2773 }
2774 }
2775 }
2776 return (0);
2777 }
2778
2779 /*
2780 * If an object specifies direct bindings (it contains a syminfo structure
2781 * describing where each binding was established during link-editing, and the
2782 * object was built -Bdirect), then look for the symbol in the specific object.
2783 */
2784 static int
lookup_sym_direct(Slookup * slp,Sresult * srp,uint_t * binfo,Syminfo * sip,Rt_map * lmp,int * in_nfavl)2785 lookup_sym_direct(Slookup *slp, Sresult *srp, uint_t *binfo, Syminfo *sip,
2786 Rt_map *lmp, int *in_nfavl)
2787 {
2788 Rt_map *dlmp, *clmp = slp->sl_cmap;
2789 int ret;
2790 Slookup sl;
2791
2792 /*
2793 * If a direct binding resolves to the definition of a copy relocated
2794 * variable, it must be redirected to the copy (in the executable) that
2795 * will eventually be made. Typically, this redirection occurs in
2796 * lookup_sym_interpose(). But, there's an edge condition. If a
2797 * directly bound executable contains pic code, there may be a
2798 * reference to a definition that will eventually have a copy made.
2799 * However, this copy relocation may not yet have occurred, because
2800 * the relocation making this reference comes before the relocation
2801 * that will create the copy.
2802 * Under direct bindings, the syminfo indicates that a copy will be
2803 * taken (SYMINFO_FLG_COPY). This can only be set in an executable.
2804 * Thus, the caller must be the executable, so bind to the destination
2805 * of the copy within the executable.
2806 */
2807 if (((slp->sl_flags & LKUP_COPY) == 0) &&
2808 (sip->si_flags & SYMINFO_FLG_COPY)) {
2809 slp->sl_imap = LIST(clmp)->lm_head;
2810
2811 ret = SYMINTP(clmp)(slp, srp, binfo, in_nfavl);
2812 if (ret != 0)
2813 *binfo |= (DBG_BINFO_DIRECT | DBG_BINFO_COPYREF);
2814 return (ret);
2815 }
2816
2817 /*
2818 * If we need to directly bind to our parent, start looking in each
2819 * callers link map.
2820 */
2821 sl = *slp;
2822 sl.sl_flags |= LKUP_DIRECT;
2823 ret = 0;
2824
2825 if (sip->si_boundto == SYMINFO_BT_PARENT) {
2826 Aliste idx1;
2827 Bnd_desc *bdp;
2828 Grp_hdl *ghp;
2829
2830 /*
2831 * Determine the parent of this explicit dependency from its
2832 * CALLERS()'s list.
2833 */
2834 for (APLIST_TRAVERSE(CALLERS(clmp), idx1, bdp)) {
2835 sl.sl_imap = lmp = bdp->b_caller;
2836 ret = SYMINTP(lmp)(&sl, srp, binfo, in_nfavl);
2837 if (ret != 0)
2838 goto found;
2839 }
2840
2841 /*
2842 * A caller can also be defined as the parent of a dlopen()
2843 * call. Determine whether this object has any handles. The
2844 * dependencies maintained with the handle represent the
2845 * explicit dependencies of the dlopen()'ed object, and the
2846 * calling parent.
2847 */
2848 for (APLIST_TRAVERSE(HANDLES(clmp), idx1, ghp)) {
2849 Grp_desc *gdp;
2850 Aliste idx2;
2851
2852 for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
2853 if ((gdp->gd_flags & GPD_PARENT) == 0)
2854 continue;
2855 sl.sl_imap = lmp = gdp->gd_depend;
2856 ret = SYMINTP(lmp)(&sl, srp, binfo, in_nfavl);
2857 if (ret != 0)
2858 goto found;
2859 }
2860 }
2861 } else {
2862 /*
2863 * If we need to direct bind to anything else look in the
2864 * link map associated with this symbol reference.
2865 */
2866 if (sip->si_boundto == SYMINFO_BT_SELF)
2867 sl.sl_imap = lmp = clmp;
2868 else
2869 sl.sl_imap = lmp;
2870
2871 if (lmp)
2872 ret = SYMINTP(lmp)(&sl, srp, binfo, in_nfavl);
2873 }
2874 found:
2875 if (ret)
2876 *binfo |= DBG_BINFO_DIRECT;
2877
2878 /*
2879 * If a reference to a directly bound symbol can't be satisfied, then
2880 * determine whether an interposer can provide the missing symbol. If
2881 * a reference to a directly bound symbol is satisfied, then determine
2882 * whether that object can be interposed upon for this symbol.
2883 */
2884 dlmp = srp->sr_dmap;
2885 if ((ret == 0) || (dlmp && (LIST(dlmp)->lm_head != dlmp) &&
2886 (LIST(dlmp) == LIST(clmp)))) {
2887 if (lookup_sym_interpose(slp, srp, binfo, in_nfavl))
2888 return (1);
2889 }
2890
2891 return (ret);
2892 }
2893
2894 static int
core_lookup_sym(Rt_map * ilmp,Slookup * slp,Sresult * srp,uint_t * binfo,Aliste off,int * in_nfavl)2895 core_lookup_sym(Rt_map *ilmp, Slookup *slp, Sresult *srp, uint_t *binfo,
2896 Aliste off, int *in_nfavl)
2897 {
2898 Rt_map *lmp;
2899
2900 /*
2901 * Copy relocations should start their search after the head of the
2902 * main link-map control list.
2903 */
2904 if ((off == ALIST_OFF_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp)
2905 lmp = NEXT_RT_MAP(ilmp);
2906 else
2907 lmp = ilmp;
2908
2909 for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
2910 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) {
2911
2912 slp->sl_imap = lmp;
2913 if ((SYMINTP(lmp)(slp, srp, binfo, in_nfavl)) ||
2914 (*binfo & BINFO_MSK_TRYAGAIN))
2915 return (1);
2916 }
2917 }
2918 return (0);
2919 }
2920
2921 static int
rescan_lazy_find_sym(Rt_map * ilmp,Slookup * slp,Sresult * srp,uint_t * binfo,int * in_nfavl)2922 rescan_lazy_find_sym(Rt_map *ilmp, Slookup *slp, Sresult *srp, uint_t *binfo,
2923 int *in_nfavl)
2924 {
2925 Rt_map *lmp;
2926
2927 for (lmp = ilmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
2928 if (LAZY(lmp) == 0)
2929 continue;
2930 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) {
2931
2932 slp->sl_imap = lmp;
2933 if (elf_lazy_find_sym(slp, srp, binfo, in_nfavl))
2934 return (1);
2935 }
2936 }
2937 return (0);
2938 }
2939
2940 static int
_lookup_sym(Slookup * slp,Sresult * srp,uint_t * binfo,int * in_nfavl)2941 _lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
2942 {
2943 const char *name = slp->sl_name;
2944 Rt_map *clmp = slp->sl_cmap;
2945 Lm_list *lml = LIST(clmp);
2946 Rt_map *ilmp = slp->sl_imap, *lmp;
2947 ulong_t rsymndx;
2948 int ret;
2949 Syminfo *sip;
2950 Slookup sl;
2951
2952 /*
2953 * Search the initial link map for the required symbol (this category is
2954 * selected by dlsym(), where individual link maps are searched for a
2955 * required symbol. Therefore, we know we have permission to look at
2956 * the link map).
2957 */
2958 if (slp->sl_flags & LKUP_FIRST)
2959 return (SYMINTP(ilmp)(slp, srp, binfo, in_nfavl));
2960
2961 /*
2962 * Determine whether this lookup can be satisfied by an objects direct,
2963 * or lazy binding information. This is triggered by a relocation from
2964 * the object (hence rsymndx is set).
2965 */
2966 if (((rsymndx = slp->sl_rsymndx) != 0) &&
2967 ((sip = SYMINFO(clmp)) != NULL)) {
2968 uint_t bound;
2969
2970 /*
2971 * Find the corresponding Syminfo entry for the original
2972 * referencing symbol.
2973 */
2974 /* LINTED */
2975 sip = (Syminfo *)((char *)sip + (rsymndx * SYMINENT(clmp)));
2976 bound = sip->si_boundto;
2977
2978 /*
2979 * Identify any EXTERN or PARENT references for ldd(1).
2980 */
2981 if ((lml->lm_flags & LML_FLG_TRC_WARN) &&
2982 (bound > SYMINFO_BT_LOWRESERVE)) {
2983 if (bound == SYMINFO_BT_PARENT)
2984 *binfo |= DBG_BINFO_REF_PARENT;
2985 if (bound == SYMINFO_BT_EXTERN)
2986 *binfo |= DBG_BINFO_REF_EXTERN;
2987 }
2988
2989 /*
2990 * If the symbol information indicates a direct binding,
2991 * determine the link map that is required to satisfy the
2992 * binding. Note, if the dependency can not be found, but a
2993 * direct binding isn't required, we will still fall through
2994 * to perform any default symbol search.
2995 */
2996 if (sip->si_flags & SYMINFO_FLG_DIRECT) {
2997
2998 lmp = 0;
2999 if (bound < SYMINFO_BT_LOWRESERVE)
3000 lmp = elf_lazy_load(clmp, slp, bound,
3001 name, 0, NULL, in_nfavl);
3002
3003 /*
3004 * If direct bindings have been disabled, and this isn't
3005 * a translator, skip any direct binding now that we've
3006 * ensured the resolving object has been loaded.
3007 *
3008 * If we need to direct bind to anything, we look in
3009 * ourselves, our parent, or in the link map we've just
3010 * loaded. Otherwise, even though we may have lazily
3011 * loaded an object we still continue to search for
3012 * symbols from the head of the link map list.
3013 */
3014 if (((FLAGS(clmp) & FLG_RT_TRANS) ||
3015 (((lml->lm_tflags & LML_TFLG_NODIRECT) == 0) &&
3016 ((slp->sl_flags & LKUP_SINGLETON) == 0))) &&
3017 ((FLAGS1(clmp) & FL1_RT_DIRECT) ||
3018 (sip->si_flags & SYMINFO_FLG_DIRECTBIND))) {
3019 ret = lookup_sym_direct(slp, srp, binfo,
3020 sip, lmp, in_nfavl);
3021
3022 /*
3023 * Determine whether this direct binding has
3024 * been rejected. If we've bound to a singleton
3025 * without following a singleton search, then
3026 * return. The caller detects this condition
3027 * and will trigger a new singleton search.
3028 *
3029 * For any other rejection (such as binding to
3030 * a symbol labeled as nodirect - presumably
3031 * because the symbol definition has been
3032 * changed since the referring object was last
3033 * built), fall through to a standard symbol
3034 * search.
3035 */
3036 if (((*binfo & BINFO_MSK_REJECTED) == 0) ||
3037 (*binfo & BINFO_MSK_TRYAGAIN))
3038 return (ret);
3039
3040 *binfo &= ~BINFO_MSK_REJECTED;
3041 }
3042 }
3043 }
3044
3045 /*
3046 * Duplicate the lookup information, as we'll need to modify this
3047 * information for some of the following searches.
3048 */
3049 sl = *slp;
3050
3051 /*
3052 * If the referencing object has the DF_SYMBOLIC flag set, look in the
3053 * referencing object for the symbol first. Failing that, fall back to
3054 * our generic search.
3055 */
3056 if ((FLAGS1(clmp) & FL1_RT_SYMBOLIC) &&
3057 ((sl.sl_flags & LKUP_SINGLETON) == 0)) {
3058
3059 sl.sl_imap = clmp;
3060 if (SYMINTP(clmp)(&sl, srp, binfo, in_nfavl)) {
3061 Rt_map *dlmp = srp->sr_dmap;
3062 ulong_t dsymndx = (((ulong_t)srp->sr_sym -
3063 (ulong_t)SYMTAB(dlmp)) / SYMENT(dlmp));
3064
3065 /*
3066 * Make sure this symbol hasn't explicitly been defined
3067 * as nodirect.
3068 */
3069 if (((sip = SYMINFO(dlmp)) == 0) ||
3070 /* LINTED */
3071 ((sip = (Syminfo *)((char *)sip +
3072 (dsymndx * SYMINENT(dlmp)))) == 0) ||
3073 ((sip->si_flags & SYMINFO_FLG_NOEXTDIRECT) == 0))
3074 return (1);
3075 }
3076 }
3077
3078 sl.sl_flags |= LKUP_STANDARD;
3079
3080 /*
3081 * If this lookup originates from a standard relocation, then traverse
3082 * all link-map control lists, inspecting any object that is available
3083 * to this caller. Otherwise, traverse the link-map control list
3084 * associated with the caller.
3085 */
3086 if (sl.sl_flags & LKUP_STDRELOC) {
3087 Aliste off;
3088 Lm_cntl *lmc;
3089
3090 ret = 0;
3091
3092 for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) {
3093 if (((ret = core_lookup_sym(lmc->lc_head, &sl, srp,
3094 binfo, off, in_nfavl)) != 0) ||
3095 (*binfo & BINFO_MSK_TRYAGAIN))
3096 break;
3097 }
3098 } else
3099 ret = core_lookup_sym(ilmp, &sl, srp, binfo, ALIST_OFF_DATA,
3100 in_nfavl);
3101
3102 /*
3103 * If a symbol binding should be retried, return so that the search can
3104 * be repeated.
3105 */
3106 if (*binfo & BINFO_MSK_TRYAGAIN)
3107 return (0);
3108
3109 /*
3110 * To allow transitioning into a world of lazy loading dependencies see
3111 * if this link map contains objects that have lazy dependencies still
3112 * outstanding. If so, and we haven't been able to locate a non-weak
3113 * symbol reference, start bringing in any lazy dependencies to see if
3114 * the reference can be satisfied. Use of dlsym(RTLD_PROBE) sets the
3115 * LKUP_NOFALLBACK flag, and this flag disables this fall back.
3116 */
3117 if ((ret == 0) && ((sl.sl_flags & LKUP_NOFALLBACK) == 0)) {
3118 if ((lmp = ilmp) == 0)
3119 lmp = LIST(clmp)->lm_head;
3120
3121 lml = LIST(lmp);
3122 if ((sl.sl_flags & LKUP_WEAK) || (lml->lm_lazy == 0))
3123 return (0);
3124
3125 DBG_CALL(Dbg_syms_lazy_rescan(lml, name));
3126
3127 /*
3128 * If this request originated from a dlsym(RTLD_NEXT) then start
3129 * looking for dependencies from the caller, otherwise use the
3130 * initial link-map.
3131 */
3132 if (sl.sl_flags & LKUP_NEXT)
3133 ret = rescan_lazy_find_sym(clmp, &sl, srp, binfo,
3134 in_nfavl);
3135 else {
3136 Aliste idx;
3137 Lm_cntl *lmc;
3138
3139 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
3140 sl.sl_flags |= LKUP_NOFALLBACK;
3141 ret = rescan_lazy_find_sym(lmc->lc_head,
3142 &sl, srp, binfo, in_nfavl);
3143 if (ret != 0)
3144 break;
3145 }
3146 }
3147 }
3148 return (ret);
3149 }
3150
3151 /*
3152 * Symbol lookup routine. Takes an ELF symbol name, and a list of link maps to
3153 * search. If successful, return a pointer to the symbol table entry, a
3154 * pointer to the link map of the enclosing object, and information relating
3155 * to the type of binding. Else return a null pointer.
3156 */
3157 int
lookup_sym(Slookup * slp,Sresult * srp,uint_t * binfo,int * in_nfavl)3158 lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
3159 {
3160 Rt_map *clmp = slp->sl_cmap;
3161 Sym *rsym = slp->sl_rsym;
3162 uchar_t rtype = slp->sl_rtype, vis;
3163 int ret, mode;
3164
3165 if (slp->sl_hash == 0)
3166 slp->sl_hash = elf_hash(slp->sl_name);
3167 *binfo = 0;
3168
3169 if (rsym) {
3170 vis = ELF_ST_VISIBILITY(rsym->st_other);
3171
3172 /*
3173 * Symbols that are defined as protected, or hidden, within an
3174 * object usually have any relocation references from within
3175 * the same object bound at link-edit time. Therefore, ld.so.1
3176 * is not involved. However, if a reference is to a
3177 * capabilities symbol, this reference must be resolved at
3178 * runtime. In this case look directly within the calling
3179 * object, and only within the calling object, for these
3180 * symbols. Note, an object may still use dlsym() to search
3181 * externally for a symbol which is defined as protected within
3182 * the same object.
3183 */
3184 if ((rsym->st_shndx != SHN_UNDEF) &&
3185 ((slp->sl_flags & LKUP_DLSYM) == 0) &&
3186 ((vis == STV_PROTECTED) || (vis == STV_HIDDEN))) {
3187 slp->sl_imap = clmp;
3188 return (SYMINTP(clmp)(slp, srp, binfo, in_nfavl));
3189 }
3190
3191 /*
3192 * Establish any state that might be associated with a symbol
3193 * reference.
3194 */
3195 if ((slp->sl_flags & LKUP_STDRELOC) &&
3196 (ELF_ST_BIND(rsym->st_info) == STB_WEAK))
3197 slp->sl_flags |= LKUP_WEAK;
3198
3199 if (vis == STV_SINGLETON)
3200 slp->sl_flags |= LKUP_SINGLETON;
3201 }
3202
3203 /*
3204 * Establish any lookup state required for this type of relocation.
3205 */
3206 if ((slp->sl_flags & LKUP_STDRELOC) && rtype) {
3207 if (rtype == M_R_COPY)
3208 slp->sl_flags |= LKUP_COPY;
3209
3210 if (rtype != M_R_JMP_SLOT)
3211 slp->sl_flags |= LKUP_SPEC;
3212 }
3213
3214 /*
3215 * Under ldd -w, any unresolved weak references are diagnosed. Set the
3216 * symbol binding as global to trigger a relocation error if the symbol
3217 * can not be found.
3218 */
3219 if (rsym) {
3220 if (LIST(slp->sl_cmap)->lm_flags & LML_FLG_TRC_NOUNRESWEAK)
3221 slp->sl_bind = STB_GLOBAL;
3222 else if ((slp->sl_bind = ELF_ST_BIND(rsym->st_info)) ==
3223 STB_WEAK)
3224 slp->sl_flags |= LKUP_WEAK;
3225 }
3226
3227 /*
3228 * Save the callers MODE().
3229 */
3230 mode = MODE(clmp);
3231
3232 /*
3233 * Carry out an initial symbol search. This search takes into account
3234 * all the modes of the requested search.
3235 */
3236 if (((ret = _lookup_sym(slp, srp, binfo, in_nfavl)) == 0) &&
3237 (*binfo & BINFO_MSK_TRYAGAIN)) {
3238 Slookup sl = *slp;
3239
3240 /*
3241 * Try the symbol search again. This retry can be necessary if:
3242 *
3243 * - a binding has been rejected because of binding to a
3244 * singleton without going through a singleton search.
3245 * - a group binding has resulted in binding to a symbol
3246 * that indicates no-direct binding.
3247 *
3248 * Reset the lookup data, and try again.
3249 */
3250 sl.sl_imap = LIST(sl.sl_cmap)->lm_head;
3251 sl.sl_flags &= ~(LKUP_FIRST | LKUP_SELF | LKUP_NEXT);
3252 sl.sl_rsymndx = 0;
3253
3254 if (*binfo & BINFO_REJSINGLE)
3255 sl.sl_flags |= LKUP_SINGLETON;
3256 if (*binfo & BINFO_REJGROUP) {
3257 sl.sl_flags |= LKUP_WORLD;
3258 mode |= RTLD_WORLD;
3259 }
3260 *binfo &= ~BINFO_MSK_REJECTED;
3261
3262 ret = _lookup_sym(&sl, srp, binfo, in_nfavl);
3263 }
3264
3265 /*
3266 * If the caller is restricted to a symbol search within its group,
3267 * determine if it is necessary to follow a binding from outside of
3268 * the group.
3269 */
3270 if (((mode & (RTLD_GROUP | RTLD_WORLD)) == RTLD_GROUP) &&
3271 (lookup_sym_interpose(slp, srp, binfo, in_nfavl)))
3272 return (1);
3273
3274 return (ret);
3275 }
3276
3277 /*
3278 * Associate a binding descriptor with a caller and its dependency, or update
3279 * an existing descriptor.
3280 */
3281 int
bind_one(Rt_map * clmp,Rt_map * dlmp,uint_t flags)3282 bind_one(Rt_map *clmp, Rt_map *dlmp, uint_t flags)
3283 {
3284 Bnd_desc *bdp;
3285 Aliste idx;
3286 int found = ALE_CREATE;
3287
3288 /*
3289 * Determine whether a binding descriptor already exists between the
3290 * two objects.
3291 */
3292 for (APLIST_TRAVERSE(DEPENDS(clmp), idx, bdp)) {
3293 if (bdp->b_depend == dlmp) {
3294 found = ALE_EXISTS;
3295 break;
3296 }
3297 }
3298
3299 if (found == ALE_CREATE) {
3300 /*
3301 * Create a new binding descriptor.
3302 */
3303 if ((bdp = malloc(sizeof (Bnd_desc))) == NULL)
3304 return (0);
3305
3306 bdp->b_caller = clmp;
3307 bdp->b_depend = dlmp;
3308 bdp->b_flags = 0;
3309
3310 /*
3311 * Append the binding descriptor to the caller and the
3312 * dependency.
3313 */
3314 if (aplist_append(&DEPENDS(clmp), bdp, AL_CNT_DEPENDS) == NULL)
3315 return (0);
3316
3317 if (aplist_append(&CALLERS(dlmp), bdp, AL_CNT_CALLERS) == NULL)
3318 return (0);
3319 }
3320
3321 if ((found == ALE_CREATE) || ((bdp->b_flags & flags) != flags)) {
3322 bdp->b_flags |= flags;
3323
3324 if (flags & BND_REFER)
3325 FLAGS1(dlmp) |= FL1_RT_USED;
3326
3327 DBG_CALL(Dbg_file_bind_entry(LIST(clmp), bdp));
3328 }
3329 return (found);
3330 }
3331
3332 /*
3333 * Cleanup after relocation processing.
3334 */
3335 int
relocate_finish(Rt_map * lmp,APlist * bound,int ret)3336 relocate_finish(Rt_map *lmp, APlist *bound, int ret)
3337 {
3338 DBG_CALL(Dbg_reloc_run(lmp, 0, ret, DBG_REL_FINISH));
3339
3340 /*
3341 * Establish bindings to all objects that have been bound to.
3342 */
3343 if (bound) {
3344 Rt_map *_lmp;
3345 Word used;
3346
3347 /*
3348 * Only create bindings if the callers relocation was
3349 * successful (ret != 0), otherwise the object will eventually
3350 * be torn down. Create these bindings if running under ldd(1)
3351 * with the -U/-u options regardless of relocation errors, as
3352 * the unused processing needs to traverse these bindings to
3353 * diagnose unused objects.
3354 */
3355 used = LIST(lmp)->lm_flags &
3356 (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED);
3357
3358 if (ret || used) {
3359 Aliste idx;
3360
3361 for (APLIST_TRAVERSE(bound, idx, _lmp)) {
3362 if (bind_one(lmp, _lmp, BND_REFER) || used)
3363 continue;
3364
3365 ret = 0;
3366 break;
3367 }
3368 }
3369 free(bound);
3370 }
3371
3372 return (ret);
3373 }
3374
3375 /*
3376 * Function to correct protection settings. Segments are all mapped initially
3377 * with permissions as given in the segment header. We need to turn on write
3378 * permissions on a text segment if there are any relocations against that
3379 * segment, and then turn write permission back off again before returning
3380 * control to the caller. This function turns the permission on or off
3381 * depending on the value of the permission argument.
3382 */
3383 int
set_prot(Rt_map * lmp,mmapobj_result_t * mpp,int perm)3384 set_prot(Rt_map *lmp, mmapobj_result_t *mpp, int perm)
3385 {
3386 int prot;
3387
3388 /*
3389 * If this is an allocated image (ie. a relocatable object) we can't
3390 * mprotect() anything.
3391 */
3392 if (FLAGS(lmp) & FLG_RT_IMGALLOC)
3393 return (1);
3394
3395 DBG_CALL(Dbg_file_prot(lmp, perm));
3396
3397 if (perm)
3398 prot = mpp->mr_prot | PROT_WRITE;
3399 else
3400 prot = mpp->mr_prot & ~PROT_WRITE;
3401
3402 if (mprotect((void *)(uintptr_t)mpp->mr_addr,
3403 mpp->mr_msize, prot) == -1) {
3404 int err = errno;
3405 eprintf(LIST(lmp), ERR_FATAL, MSG_INTL(MSG_SYS_MPROT),
3406 NAME(lmp), strerror(err));
3407 return (0);
3408 }
3409 mpp->mr_prot = prot;
3410 return (1);
3411 }
3412