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