1/* Copyright (C) 1999-2021 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Andreas Jaeger <aj@suse.de>, 1999.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
17
18#define PROCINFO_CLASS static
19#include <assert.h>
20#include <alloca.h>
21#include <argp.h>
22#include <dirent.h>
23#include <elf.h>
24#include <error.h>
25#include <errno.h>
26#include <inttypes.h>
27#include <libintl.h>
28#include <locale.h>
29#include <stdbool.h>
30#include <stdio.h>
31#include <stdio_ext.h>
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35#include <stdint.h>
36#include <sys/fcntl.h>
37#include <sys/mman.h>
38#include <sys/stat.h>
39#include <sys/types.h>
40#include <glob.h>
41#include <libgen.h>
42
43#include <ldconfig.h>
44#include <dl-cache.h>
45#include <dl-hwcaps.h>
46#include <dl-is_dso.h>
47
48#include <dl-procinfo.h>
49
50/* This subpath in search path entries is always supported and
51 included in the cache for backwards compatibility. */
52#define TLS_SUBPATH "tls"
53
54/* The MSB of the hwcap field is set for objects in TLS_SUBPATH
55 directories. There is always TLS support in glibc, so the dynamic
56 loader does not check the bit directly. But more hwcap bits make a
57 an object more preferred, so the bit still has meaning. */
58#define TLS_HWCAP_BIT 63
59
60#ifndef LD_SO_CONF
61# define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
62#endif
63
64/* Get libc version number. */
65#include <version.h>
66
67#define PACKAGE _libc_intl_domainname
68
69static const struct
70{
71 const char *name;
72 int flag;
73} lib_types[] =
74{
75 {"libc4", FLAG_LIBC4},
76 {"libc5", FLAG_ELF_LIBC5},
77 {"libc6", FLAG_ELF_LIBC6},
78 {"glibc2", FLAG_ELF_LIBC6}
79};
80
81
82/* List of directories to handle. */
83struct dir_entry
84{
85 char *path;
86 int flag;
87 ino64_t ino;
88 dev_t dev;
89 const char *from_file;
90 int from_line;
91
92 /* Non-NULL for subdirectories under a glibc-hwcaps subdirectory. */
93 struct glibc_hwcaps_subdirectory *hwcaps;
94
95 struct dir_entry *next;
96};
97
98/* The list is unsorted, contains no duplicates. Entries are added at
99 the end. */
100static struct dir_entry *dir_entries;
101
102/* Flags for different options. */
103/* Print Cache. */
104static int opt_print_cache;
105
106/* Be verbose. */
107int opt_verbose;
108
109/* Format to support. */
110enum opt_format opt_format = opt_format_new;
111
112/* Build cache. */
113static int opt_build_cache = 1;
114
115/* Enable symbolic link processing. If set, create or update symbolic
116 links, and remove stale symbolic links. */
117static int opt_link = 1;
118
119/* Only process directories specified on the command line. */
120static int opt_only_cline;
121
122/* Path to root for chroot. */
123static char *opt_chroot;
124
125/* Manually link given shared libraries. */
126static int opt_manual_link;
127
128/* Should we ignore an old auxiliary cache file? */
129static int opt_ignore_aux_cache;
130
131/* Cache file to use. */
132static char *cache_file;
133
134/* Configuration file. */
135static const char *config_file;
136
137/* Mask to use for important hardware capabilities. */
138static unsigned long int hwcap_mask = HWCAP_IMPORTANT;
139
140/* Name and version of program. */
141static void print_version (FILE *stream, struct argp_state *state);
142void (*argp_program_version_hook) (FILE *, struct argp_state *)
143 = print_version;
144
145/* Function to print some extra text in the help message. */
146static char *more_help (int key, const char *text, void *input);
147
148/* Definitions of arguments for argp functions. */
149static const struct argp_option options[] =
150{
151 { "print-cache", 'p', NULL, 0, N_("Print cache"), 0},
152 { "verbose", 'v', NULL, 0, N_("Generate verbose messages"), 0},
153 { NULL, 'N', NULL, 0, N_("Don't build cache"), 0},
154 { NULL, 'X', NULL, 0, N_("Don't update symbolic links"), 0},
155 { NULL, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
156 { NULL, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
157 { NULL, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
158 { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
159 { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
160 { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new (default), old, or compat"), 0},
161 { "ignore-aux-cache", 'i', NULL, 0, N_("Ignore auxiliary cache file"), 0},
162 { NULL, 0, NULL, 0, NULL, 0 }
163};
164
165#define PROCINFO_CLASS static
166#include <dl-procinfo.c>
167
168/* Short description of program. */
169static const char doc[] = N_("Configure Dynamic Linker Run Time Bindings.");
170
171/* Prototype for option handler. */
172static error_t parse_opt (int key, char *arg, struct argp_state *state);
173
174/* Data structure to communicate with argp functions. */
175static struct argp argp =
176{
177 options, parse_opt, NULL, doc, NULL, more_help, NULL
178};
179
180/* Check if string corresponds to an important hardware capability or
181 a platform. */
182static int
183is_hwcap_platform (const char *name)
184{
185 int hwcap_idx = _dl_string_hwcap (name);
186
187 /* Is this a normal hwcap for the machine like "fpu?" */
188 if (hwcap_idx != -1 && ((1 << hwcap_idx) & hwcap_mask))
189 return 1;
190
191 /* Is this a platform pseudo-hwcap like "i686?" */
192 hwcap_idx = _dl_string_platform (name);
193 if (hwcap_idx != -1)
194 return 1;
195
196 /* Backwards-compatibility for the "tls" subdirectory. */
197 if (strcmp (name, TLS_SUBPATH) == 0)
198 return 1;
199
200 return 0;
201}
202
203/* Get hwcap (including platform) encoding of path. */
204static uint64_t
205path_hwcap (const char *path)
206{
207 char *str = xstrdup (path);
208 char *ptr;
209 uint64_t hwcap = 0;
210 uint64_t h;
211
212 size_t len;
213
214 len = strlen (str);
215 if (str[len] == '/')
216 str[len] = '\0';
217
218 /* Search pathname from the end and check for hwcap strings. */
219 for (;;)
220 {
221 ptr = strrchr (str, '/');
222
223 if (ptr == NULL)
224 break;
225
226 h = _dl_string_hwcap (ptr + 1);
227
228 if (h == (uint64_t) -1)
229 {
230 h = _dl_string_platform (ptr + 1);
231 if (h == (uint64_t) -1)
232 {
233 if (strcmp (ptr + 1, TLS_SUBPATH) == 0)
234 h = TLS_HWCAP_BIT;
235 else
236 break;
237 }
238 }
239 hwcap += 1ULL << h;
240
241 /* Search the next part of the path. */
242 *ptr = '\0';
243 }
244
245 free (str);
246 return hwcap;
247}
248
249/* Handle program arguments. */
250static error_t
251parse_opt (int key, char *arg, struct argp_state *state)
252{
253 switch (key)
254 {
255 case 'C':
256 cache_file = arg;
257 /* Ignore auxiliary cache since we use non-standard cache. */
258 opt_ignore_aux_cache = 1;
259 break;
260 case 'f':
261 config_file = arg;
262 break;
263 case 'i':
264 opt_ignore_aux_cache = 1;
265 break;
266 case 'l':
267 opt_manual_link = 1;
268 break;
269 case 'N':
270 opt_build_cache = 0;
271 break;
272 case 'n':
273 opt_build_cache = 0;
274 opt_only_cline = 1;
275 break;
276 case 'p':
277 opt_print_cache = 1;
278 break;
279 case 'r':
280 opt_chroot = arg;
281 break;
282 case 'v':
283 opt_verbose = 1;
284 break;
285 case 'X':
286 opt_link = 0;
287 break;
288 case 'c':
289 if (strcmp (arg, "old") == 0)
290 opt_format = opt_format_old;
291 else if (strcmp (arg, "compat") == 0)
292 opt_format = opt_format_compat;
293 else if (strcmp (arg, "new") == 0)
294 opt_format = opt_format_new;
295 break;
296 default:
297 return ARGP_ERR_UNKNOWN;
298 }
299
300 return 0;
301}
302
303/* Print bug-reporting information in the help message. */
304static char *
305more_help (int key, const char *text, void *input)
306{
307 char *tp = NULL;
308 switch (key)
309 {
310 case ARGP_KEY_HELP_EXTRA:
311 /* We print some extra information. */
312 if (asprintf (&tp, gettext ("\
313For bug reporting instructions, please see:\n\
314%s.\n"), REPORT_BUGS_TO) < 0)
315 return NULL;
316 return tp;
317 default:
318 break;
319 }
320 return (char *) text;
321}
322
323/* Print the version information. */
324static void
325print_version (FILE *stream, struct argp_state *state)
326{
327 fprintf (stream, "ldconfig %s%s\n", PKGVERSION, VERSION);
328 fprintf (stream, gettext ("\
329Copyright (C) %s Free Software Foundation, Inc.\n\
330This is free software; see the source for copying conditions. There is NO\n\
331warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
332"), "2021");
333 fprintf (stream, gettext ("Written by %s.\n"),
334 "Andreas Jaeger");
335}
336
337/* Allocate a new subdirectory with full path PATH under ENTRY, using
338 inode data from *ST. */
339static struct dir_entry *
340new_sub_entry (const struct dir_entry *entry, const char *path,
341 const struct stat64 *st)
342{
343 struct dir_entry *new_entry = xmalloc (sizeof (struct dir_entry));
344 new_entry->from_file = entry->from_file;
345 new_entry->from_line = entry->from_line;
346 new_entry->path = xstrdup (path);
347 new_entry->flag = entry->flag;
348 new_entry->hwcaps = NULL;
349 new_entry->next = NULL;
350 new_entry->ino = st->st_ino;
351 new_entry->dev = st->st_dev;
352 return new_entry;
353}
354
355/* Add a single directory entry. Return true if the directory is
356 actually added (because it is not a duplicate). */
357static bool
358add_single_dir (struct dir_entry *entry, int verbose)
359{
360 struct dir_entry *ptr, *prev;
361 bool added = true;
362
363 ptr = dir_entries;
364 prev = ptr;
365 while (ptr != NULL)
366 {
367 /* Check for duplicates. */
368 if (ptr->ino == entry->ino && ptr->dev == entry->dev)
369 {
370 if (opt_verbose && verbose)
371 {
372 error (0, 0, _("Path `%s' given more than once"), entry->path);
373 fprintf (stderr, _("(from %s:%d and %s:%d)\n"),
374 entry->from_file, entry->from_line,
375 ptr->from_file, ptr->from_line);
376 }
377 /* Use the newer information. */
378 ptr->flag = entry->flag;
379 free (entry->path);
380 free (entry);
381 added = false;
382 break;
383 }
384 prev = ptr;
385 ptr = ptr->next;
386 }
387 /* Is this the first entry? */
388 if (ptr == NULL && dir_entries == NULL)
389 dir_entries = entry;
390 else if (ptr == NULL)
391 prev->next = entry;
392 return added;
393}
394
395/* Check if PATH contains a "glibc-hwcaps" subdirectory. If so, queue
396 its subdirectories for glibc-hwcaps processing. */
397static void
398add_glibc_hwcaps_subdirectories (struct dir_entry *entry, const char *path)
399{
400 /* glibc-hwcaps subdirectories do not nest. */
401 assert (entry->hwcaps == NULL);
402
403 char *glibc_hwcaps;
404 if (asprintf (&glibc_hwcaps, "%s/" GLIBC_HWCAPS_SUBDIRECTORY, path) < 0)
405 error (EXIT_FAILURE, errno, _("Could not form glibc-hwcaps path"));
406
407 DIR *dir = opendir (glibc_hwcaps);
408 if (dir != NULL)
409 {
410 while (true)
411 {
412 errno = 0;
413 struct dirent64 *e = readdir64 (dir);
414 if (e == NULL)
415 {
416 if (errno == 0)
417 break;
418 else
419 error (EXIT_FAILURE, errno, _("Listing directory %s"), path);
420 }
421
422 /* Ignore hidden subdirectories, including "." and "..", and
423 regular files. File names containing a ':' cannot be
424 looked up by the dynamic loader, so skip those as
425 well. */
426 if (e->d_name[0] == '.' || e->d_type == DT_REG
427 || strchr (e->d_name, ':') != NULL)
428 continue;
429
430 /* See if this entry eventually resolves to a directory. */
431 struct stat64 st;
432 if (fstatat64 (dirfd (dir), e->d_name, &st, 0) < 0)
433 /* Ignore unreadable entries. */
434 continue;
435
436 if (S_ISDIR (st.st_mode))
437 {
438 /* This is a directory, so it needs to be scanned for
439 libraries, associated with the hwcaps implied by the
440 subdirectory name. */
441 char *new_path;
442 if (asprintf (&new_path, "%s/" GLIBC_HWCAPS_SUBDIRECTORY "/%s",
443 /* Use non-canonicalized path here. */
444 entry->path, e->d_name) < 0)
445 error (EXIT_FAILURE, errno,
446 _("Could not form glibc-hwcaps path"));
447 struct dir_entry *new_entry = new_sub_entry (entry, new_path,
448 &st);
449 free (new_path);
450 new_entry->hwcaps = new_glibc_hwcaps_subdirectory (e->d_name);
451 add_single_dir (new_entry, 0);
452 }
453 }
454
455 closedir (dir);
456 }
457
458 free (glibc_hwcaps);
459}
460
461/* Add one directory to the list of directories to process. */
462static void
463add_dir_1 (const char *line, const char *from_file, int from_line)
464{
465 unsigned int i;
466 struct dir_entry *entry = xmalloc (sizeof (struct dir_entry));
467 entry->hwcaps = NULL;
468 entry->next = NULL;
469
470 entry->from_file = strdup (from_file);
471 entry->from_line = from_line;
472
473 /* Search for an '=' sign. */
474 entry->path = xstrdup (line);
475 char *equal_sign = strchr (entry->path, '=');
476 if (equal_sign)
477 {
478 *equal_sign = '\0';
479 ++equal_sign;
480 entry->flag = FLAG_ANY;
481 for (i = 0; i < sizeof (lib_types) / sizeof (lib_types[0]); ++i)
482 if (strcmp (equal_sign, lib_types[i].name) == 0)
483 {
484 entry->flag = lib_types[i].flag;
485 break;
486 }
487 if (entry->flag == FLAG_ANY)
488 error (0, 0, _("%s is not a known library type"), equal_sign);
489 }
490 else
491 {
492 entry->flag = FLAG_ANY;
493 }
494
495 /* Canonify path: for now only remove leading and trailing
496 whitespace and the trailing slashes. */
497 i = strlen (entry->path);
498
499 while (i > 0 && isspace (entry->path[i - 1]))
500 entry->path[--i] = '\0';
501
502 while (i > 0 && entry->path[i - 1] == '/')
503 entry->path[--i] = '\0';
504
505 if (i == 0)
506 return;
507
508 char *path = entry->path;
509 if (opt_chroot != NULL)
510 path = chroot_canon (opt_chroot, path);
511
512 struct stat64 stat_buf;
513 if (path == NULL || stat64 (path, &stat_buf))
514 {
515 if (opt_verbose)
516 error (0, errno, _("Can't stat %s"), entry->path);
517 free (entry->path);
518 free (entry);
519 }
520 else
521 {
522 entry->ino = stat_buf.st_ino;
523 entry->dev = stat_buf.st_dev;
524
525 if (add_single_dir (entry, 1))
526 /* Add glibc-hwcaps subdirectories if present. */
527 add_glibc_hwcaps_subdirectories (entry, path);
528 }
529
530 if (opt_chroot != NULL)
531 free (path);
532}
533
534static void
535add_dir (const char *line)
536{
537 add_dir_1 (line, "<builtin>", 0);
538}
539
540static int
541chroot_stat (const char *real_path, const char *path, struct stat64 *st)
542{
543 int ret;
544 char *canon_path;
545
546 if (!opt_chroot)
547 return stat64 (real_path, st);
548
549 ret = lstat64 (real_path, st);
550 if (ret || !S_ISLNK (st->st_mode))
551 return ret;
552
553 canon_path = chroot_canon (opt_chroot, path);
554 if (canon_path == NULL)
555 return -1;
556
557 ret = stat64 (canon_path, st);
558 free (canon_path);
559 return ret;
560}
561
562/* Create a symbolic link from soname to libname in directory path. */
563static void
564create_links (const char *real_path, const char *path, const char *libname,
565 const char *soname)
566{
567 char *full_libname, *full_soname;
568 char *real_full_libname, *real_full_soname;
569 struct stat64 stat_lib, stat_so, lstat_so;
570 int do_link = 1;
571 int do_remove = 1;
572 /* XXX: The logics in this function should be simplified. */
573
574 /* Get complete path. */
575 full_libname = alloca (strlen (path) + strlen (libname) + 2);
576 full_soname = alloca (strlen (path) + strlen (soname) + 2);
577 sprintf (full_libname, "%s/%s", path, libname);
578 sprintf (full_soname, "%s/%s", path, soname);
579 if (opt_chroot != NULL)
580 {
581 real_full_libname = alloca (strlen (real_path) + strlen (libname) + 2);
582 real_full_soname = alloca (strlen (real_path) + strlen (soname) + 2);
583 sprintf (real_full_libname, "%s/%s", real_path, libname);
584 sprintf (real_full_soname, "%s/%s", real_path, soname);
585 }
586 else
587 {
588 real_full_libname = full_libname;
589 real_full_soname = full_soname;
590 }
591
592 /* Does soname already exist and point to the right library? */
593 if (chroot_stat (real_full_soname, full_soname, &stat_so) == 0)
594 {
595 if (chroot_stat (real_full_libname, full_libname, &stat_lib))
596 {
597 error (0, 0, _("Can't stat %s\n"), full_libname);
598 return;
599 }
600 if (stat_lib.st_dev == stat_so.st_dev
601 && stat_lib.st_ino == stat_so.st_ino)
602 /* Link is already correct. */
603 do_link = 0;
604 else if (lstat64 (full_soname, &lstat_so) == 0
605 && !S_ISLNK (lstat_so.st_mode))
606 {
607 error (0, 0, _("%s is not a symbolic link\n"), full_soname);
608 do_link = 0;
609 do_remove = 0;
610 }
611 }
612 else if (lstat64 (real_full_soname, &lstat_so) != 0
613 || !S_ISLNK (lstat_so.st_mode))
614 /* Unless it is a stale symlink, there is no need to remove. */
615 do_remove = 0;
616
617 if (opt_verbose)
618 printf ("\t%s -> %s", soname, libname);
619
620 if (do_link && opt_link)
621 {
622 /* Remove old link. */
623 if (do_remove)
624 if (unlink (real_full_soname))
625 {
626 error (0, 0, _("Can't unlink %s"), full_soname);
627 do_link = 0;
628 }
629 /* Create symbolic link. */
630 if (do_link && symlink (libname, real_full_soname))
631 {
632 error (0, 0, _("Can't link %s to %s"), full_soname, libname);
633 do_link = 0;
634 }
635 if (opt_verbose)
636 {
637 if (do_link)
638 fputs (_(" (changed)\n"), stdout);
639 else
640 fputs (_(" (SKIPPED)\n"), stdout);
641 }
642 }
643 else if (opt_verbose)
644 fputs ("\n", stdout);
645}
646
647/* Manually link the given library. */
648static void
649manual_link (char *library)
650{
651 char *path;
652 char *real_path;
653 char *real_library;
654 char *libname;
655 char *soname;
656 struct stat64 stat_buf;
657 int flag;
658 unsigned int osversion;
659 unsigned int isa_level;
660
661 /* Prepare arguments for create_links call. Split library name in
662 directory and filename first. Since path is allocated, we've got
663 to be careful to free at the end. */
664 path = xstrdup (library);
665 libname = strrchr (path, '/');
666
667 if (libname)
668 {
669 /* Successfully split names. Check if path is just "/" to avoid
670 an empty path. */
671 if (libname == path)
672 {
673 libname = library + 1;
674 path = xrealloc (path, 2);
675 strcpy (path, "/");
676 }
677 else
678 {
679 *libname = '\0';
680 ++libname;
681 }
682 }
683 else
684 {
685 /* There's no path, construct one. */
686 libname = library;
687 path = xrealloc (path, 2);
688 strcpy (path, ".");
689 }
690
691 if (opt_chroot != NULL)
692 {
693 real_path = chroot_canon (opt_chroot, path);
694 if (real_path == NULL)
695 {
696 error (0, errno, _("Can't find %s"), path);
697 free (path);
698 return;
699 }
700 real_library = alloca (strlen (real_path) + strlen (libname) + 2);
701 sprintf (real_library, "%s/%s", real_path, libname);
702 }
703 else
704 {
705 real_path = path;
706 real_library = library;
707 }
708
709 /* Do some sanity checks first. */
710 if (lstat64 (real_library, &stat_buf))
711 {
712 error (0, errno, _("Cannot lstat %s"), library);
713 goto out;
714 }
715 /* We don't want links here! */
716 else if (!S_ISREG (stat_buf.st_mode))
717 {
718 error (0, 0, _("Ignored file %s since it is not a regular file."),
719 library);
720 goto out;
721 }
722
723 if (process_file (real_library, library, libname, &flag, &osversion,
724 &isa_level, &soname, 0, &stat_buf))
725 {
726 error (0, 0, _("No link created since soname could not be found for %s"),
727 library);
728 goto out;
729 }
730 if (soname == NULL)
731 soname = implicit_soname (libname, flag);
732 create_links (real_path, path, libname, soname);
733 free (soname);
734out:
735 free (path);
736 if (path != real_path)
737 free (real_path);
738}
739
740
741/* Read a whole directory and search for libraries.
742 The purpose is two-fold:
743 - search for libraries which will be added to the cache
744 - create symbolic links to the soname for each library
745
746 This has to be done separatly for each directory.
747
748 To keep track of which libraries to add to the cache and which
749 links to create, we save a list of all libraries.
750
751 The algorithm is basically:
752 for all libraries in the directory do
753 get soname of library
754 if soname is already in list
755 if new library is newer, replace entry
756 otherwise ignore this library
757 otherwise add library to list
758
759 For example, if the two libraries libxy.so.1.1 and libxy.so.1.2
760 exist and both have the same soname, e.g. libxy.so, a symbolic link
761 is created from libxy.so.1.2 (the newer one) to libxy.so.
762 libxy.so.1.2 and libxy.so are added to the cache - but not
763 libxy.so.1.1. */
764
765/* Information for one library. */
766struct dlib_entry
767{
768 char *name;
769 char *soname;
770 int flag;
771 int is_link;
772 unsigned int osversion;
773 unsigned int isa_level;
774 struct dlib_entry *next;
775};
776
777
778static void
779search_dir (const struct dir_entry *entry)
780{
781 uint64_t hwcap;
782 if (entry->hwcaps == NULL)
783 {
784 hwcap = path_hwcap (entry->path);
785 if (opt_verbose)
786 {
787 if (hwcap != 0)
788 printf ("%s: (hwcap: %#.16" PRIx64 ")", entry->path, hwcap);
789 else
790 printf ("%s:", entry->path);
791 }
792 }
793 else
794 {
795 hwcap = 0;
796 if (opt_verbose)
797 printf ("%s: (hwcap: \"%s\")", entry->path,
798 glibc_hwcaps_subdirectory_name (entry->hwcaps));
799 }
800 if (opt_verbose)
801 printf (_(" (from %s:%d)\n"), entry->from_file, entry->from_line);
802
803 char *dir_name;
804 char *real_file_name;
805 size_t real_file_name_len;
806 size_t file_name_len = PATH_MAX;
807 char *file_name = alloca (file_name_len);
808 if (opt_chroot != NULL)
809 {
810 dir_name = chroot_canon (opt_chroot, entry->path);
811 real_file_name_len = PATH_MAX;
812 real_file_name = alloca (real_file_name_len);
813 }
814 else
815 {
816 dir_name = entry->path;
817 real_file_name_len = 0;
818 real_file_name = file_name;
819 }
820
821 DIR *dir;
822 if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
823 {
824 if (opt_verbose)
825 error (0, errno, _("Can't open directory %s"), entry->path);
826 if (opt_chroot != NULL && dir_name != NULL)
827 free (dir_name);
828 return;
829 }
830
831 struct dirent64 *direntry;
832 struct dlib_entry *dlibs = NULL;
833 while ((direntry = readdir64 (dir)) != NULL)
834 {
835 int flag;
836 /* We only look at links and regular files. */
837 if (direntry->d_type != DT_UNKNOWN
838 && direntry->d_type != DT_LNK
839 && direntry->d_type != DT_REG
840 && direntry->d_type != DT_DIR)
841 continue;
842 /* Does this file look like a shared library or is it a hwcap
843 subdirectory (if not already processing a glibc-hwcaps
844 subdirectory)? The dynamic linker is also considered as
845 shared library. */
846 if (!_dl_is_dso (direntry->d_name)
847 && (direntry->d_type == DT_REG
848 || (entry->hwcaps == NULL
849 && !is_hwcap_platform (direntry->d_name))))
850 continue;
851
852 size_t len = strlen (direntry->d_name);
853 /* Skip temporary files created by the prelink program. Files with
854 names like these are never really DSOs we want to look at. */
855 if (len >= sizeof (".#prelink#") - 1)
856 {
857 if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1,
858 ".#prelink#") == 0)
859 continue;
860 if (len >= sizeof (".#prelink#.XXXXXX") - 1
861 && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
862 + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
863 continue;
864 }
865 len += strlen (entry->path) + 2;
866 if (len > file_name_len)
867 {
868 file_name_len = len;
869 file_name = alloca (file_name_len);
870 if (!opt_chroot)
871 real_file_name = file_name;
872 }
873 sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
874 if (opt_chroot != NULL)
875 {
876 len = strlen (dir_name) + strlen (direntry->d_name) + 2;
877 if (len > real_file_name_len)
878 {
879 real_file_name_len = len;
880 real_file_name = alloca (real_file_name_len);
881 }
882 sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
883 }
884
885 struct stat64 lstat_buf;
886 /* We optimize and try to do the lstat call only if needed. */
887 if (direntry->d_type != DT_UNKNOWN)
888 lstat_buf.st_mode = DTTOIF (direntry->d_type);
889 else
890 if (__glibc_unlikely (lstat64 (real_file_name, &lstat_buf)))
891 {
892 error (0, errno, _("Cannot lstat %s"), file_name);
893 continue;
894 }
895
896 struct stat64 stat_buf;
897 bool is_dir;
898 int is_link = S_ISLNK (lstat_buf.st_mode);
899 if (is_link)
900 {
901 /* In case of symlink, we check if the symlink refers to
902 a directory. */
903 char *target_name = real_file_name;
904 if (opt_chroot != NULL)
905 {
906 target_name = chroot_canon (opt_chroot, file_name);
907 if (target_name == NULL)
908 {
909 if (strstr (file_name, ".so") == NULL)
910 error (0, 0, _("Input file %s not found.\n"), file_name);
911 continue;
912 }
913 }
914 if (__glibc_unlikely (stat64 (target_name, &stat_buf)))
915 {
916 if (opt_verbose)
917 error (0, errno, _("Cannot stat %s"), file_name);
918
919 /* Remove stale symlinks. */
920 if (opt_link && strstr (direntry->d_name, ".so."))
921 unlink (real_file_name);
922
923 if (opt_chroot != NULL)
924 free (target_name);
925
926 continue;
927 }
928
929 if (opt_chroot != NULL)
930 free (target_name);
931
932 is_dir = S_ISDIR (stat_buf.st_mode);
933
934 /* lstat_buf is later stored, update contents. */
935 lstat_buf.st_dev = stat_buf.st_dev;
936 lstat_buf.st_ino = stat_buf.st_ino;
937 lstat_buf.st_size = stat_buf.st_size;
938 lstat_buf.st_ctime = stat_buf.st_ctime;
939 }
940 else
941 is_dir = S_ISDIR (lstat_buf.st_mode);
942
943 /* No descending into subdirectories if this directory is a
944 glibc-hwcaps subdirectory (which are not recursive). */
945 if (entry->hwcaps == NULL
946 && is_dir && is_hwcap_platform (direntry->d_name))
947 {
948 if (!is_link
949 && direntry->d_type != DT_UNKNOWN
950 && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
951 {
952 error (0, errno, _("Cannot lstat %s"), file_name);
953 continue;
954 }
955
956 /* Handle subdirectory later. */
957 struct dir_entry *new_entry = new_sub_entry (entry, file_name,
958 &lstat_buf);
959 add_single_dir (new_entry, 0);
960 continue;
961 }
962 else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
963 continue;
964
965 char *real_name;
966 if (opt_chroot != NULL && is_link)
967 {
968 real_name = chroot_canon (opt_chroot, file_name);
969 if (real_name == NULL)
970 {
971 if (strstr (file_name, ".so") == NULL)
972 error (0, 0, _("Input file %s not found.\n"), file_name);
973 continue;
974 }
975 }
976 else
977 real_name = real_file_name;
978
979 /* Call lstat64 if not done yet. */
980 if (!is_link
981 && direntry->d_type != DT_UNKNOWN
982 && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
983 {
984 error (0, errno, _("Cannot lstat %s"), file_name);
985 continue;
986 }
987
988 /* First search whether the auxiliary cache contains this
989 library already and it's not changed. */
990 char *soname;
991 unsigned int osversion;
992 unsigned int isa_level;
993 if (!search_aux_cache (&lstat_buf, &flag, &osversion, &isa_level,
994 &soname))
995 {
996 if (process_file (real_name, file_name, direntry->d_name, &flag,
997 &osversion, &isa_level, &soname, is_link,
998 &lstat_buf))
999 {
1000 if (real_name != real_file_name)
1001 free (real_name);
1002 continue;
1003 }
1004 else if (opt_build_cache)
1005 add_to_aux_cache (&lstat_buf, flag, osversion, isa_level,
1006 soname);
1007 }
1008
1009 if (soname == NULL)
1010 soname = implicit_soname (direntry->d_name, flag);
1011
1012 /* A link may just point to itself. */
1013 if (is_link)
1014 {
1015 /* If the path the link points to isn't its soname or it is not
1016 the .so symlink for ld(1), we treat it as a normal file.
1017
1018 You should always do this:
1019
1020 libfoo.so -> SONAME -> Arbitrary package-chosen name.
1021
1022 e.g. libfoo.so -> libfoo.so.1 -> libfooimp.so.9.99.
1023 Given a SONAME of libfoo.so.1.
1024
1025 You should *never* do this:
1026
1027 libfoo.so -> libfooimp.so.9.99
1028
1029 If you do, and your SONAME is libfoo.so.1, then libfoo.so
1030 fails to point at the SONAME. In that case ldconfig may consider
1031 libfoo.so as another implementation of SONAME and will create
1032 symlinks against it causing problems when you try to upgrade
1033 or downgrade. The problems will arise because ldconfig will,
1034 depending on directory ordering, creat symlinks against libfoo.so
1035 e.g. libfoo.so.1.2 -> libfoo.so, but when libfoo.so is removed
1036 (typically by the removal of a development pacakge not required
1037 for the runtime) it will break the libfoo.so.1.2 symlink and the
1038 application will fail to start. */
1039 const char *real_base_name = basename (real_file_name);
1040
1041 if (strcmp (real_base_name, soname) != 0)
1042 {
1043 len = strlen (real_base_name);
1044 if (len < strlen (".so")
1045 || strcmp (real_base_name + len - strlen (".so"), ".so") != 0
1046 || strncmp (real_base_name, soname, len) != 0)
1047 is_link = 0;
1048 }
1049 }
1050
1051 if (real_name != real_file_name)
1052 free (real_name);
1053
1054 if (is_link)
1055 {
1056 free (soname);
1057 soname = xstrdup (direntry->d_name);
1058 }
1059
1060 if (flag == FLAG_ELF
1061 && (entry->flag == FLAG_ELF_LIBC5
1062 || entry->flag == FLAG_ELF_LIBC6))
1063 flag = entry->flag;
1064
1065 /* Some sanity checks to print warnings. */
1066 if (opt_verbose)
1067 {
1068 if (flag == FLAG_ELF_LIBC5 && entry->flag != FLAG_ELF_LIBC5
1069 && entry->flag != FLAG_ANY)
1070 error (0, 0, _("libc5 library %s in wrong directory"), file_name);
1071 if (flag == FLAG_ELF_LIBC6 && entry->flag != FLAG_ELF_LIBC6
1072 && entry->flag != FLAG_ANY)
1073 error (0, 0, _("libc6 library %s in wrong directory"), file_name);
1074 if (flag == FLAG_LIBC4 && entry->flag != FLAG_LIBC4
1075 && entry->flag != FLAG_ANY)
1076 error (0, 0, _("libc4 library %s in wrong directory"), file_name);
1077 }
1078
1079 /* Add library to list. */
1080 struct dlib_entry *dlib_ptr;
1081 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
1082 {
1083 /* Is soname already in list? */
1084 if (strcmp (dlib_ptr->soname, soname) == 0)
1085 {
1086 /* Prefer a file to a link, otherwise check which one
1087 is newer. */
1088 if ((!is_link && dlib_ptr->is_link)
1089 || (is_link == dlib_ptr->is_link
1090 && _dl_cache_libcmp (dlib_ptr->name, direntry->d_name) < 0))
1091 {
1092 /* It's newer - add it. */
1093 /* Flag should be the same - sanity check. */
1094 if (dlib_ptr->flag != flag)
1095 {
1096 if (dlib_ptr->flag == FLAG_ELF
1097 && (flag == FLAG_ELF_LIBC5 || flag == FLAG_ELF_LIBC6))
1098 dlib_ptr->flag = flag;
1099 else if ((dlib_ptr->flag == FLAG_ELF_LIBC5
1100 || dlib_ptr->flag == FLAG_ELF_LIBC6)
1101 && flag == FLAG_ELF)
1102 dlib_ptr->flag = flag;
1103 else
1104 error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
1105 dlib_ptr->name, direntry->d_name,
1106 entry->path);
1107 }
1108 free (dlib_ptr->name);
1109 dlib_ptr->name = xstrdup (direntry->d_name);
1110 dlib_ptr->is_link = is_link;
1111 dlib_ptr->osversion = osversion;
1112 dlib_ptr->isa_level = isa_level;
1113 }
1114 /* Don't add this library, abort loop. */
1115 /* Also free soname, since it's dynamically allocated. */
1116 free (soname);
1117 break;
1118 }
1119 }
1120 /* Add the library if it's not already in. */
1121 if (dlib_ptr == NULL)
1122 {
1123 dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
1124 dlib_ptr->name = xstrdup (direntry->d_name);
1125 dlib_ptr->soname = soname;
1126 dlib_ptr->flag = flag;
1127 dlib_ptr->is_link = is_link;
1128 dlib_ptr->osversion = osversion;
1129 dlib_ptr->isa_level = isa_level;
1130 /* Add at head of list. */
1131 dlib_ptr->next = dlibs;
1132 dlibs = dlib_ptr;
1133 }
1134 }
1135
1136 closedir (dir);
1137
1138 /* Now dlibs contains a list of all libs - add those to the cache
1139 and created all symbolic links. */
1140 struct dlib_entry *dlib_ptr;
1141 for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
1142 {
1143 /* The cached file name is the soname for non-glibc-hwcaps
1144 subdirectories (relying on symbolic links; this helps with
1145 library updates that change the file name), and the actual
1146 file for glibc-hwcaps subdirectories. */
1147 const char *filename;
1148 if (entry->hwcaps == NULL)
1149 {
1150 /* Don't create links to links. */
1151 if (dlib_ptr->is_link == 0)
1152 create_links (dir_name, entry->path, dlib_ptr->name,
1153 dlib_ptr->soname);
1154 filename = dlib_ptr->soname;
1155 }
1156 else
1157 {
1158 /* Do not create links in glibc-hwcaps subdirectories, but
1159 still log the cache addition. */
1160 if (opt_verbose)
1161 printf ("\t%s -> %s\n", dlib_ptr->soname, dlib_ptr->name);
1162 filename = dlib_ptr->name;
1163 }
1164 if (opt_build_cache)
1165 add_to_cache (entry->path, filename, dlib_ptr->soname,
1166 dlib_ptr->flag, dlib_ptr->osversion,
1167 dlib_ptr->isa_level, hwcap, entry->hwcaps);
1168 }
1169
1170 /* Free all resources. */
1171 while (dlibs)
1172 {
1173 dlib_ptr = dlibs;
1174 free (dlib_ptr->soname);
1175 free (dlib_ptr->name);
1176 dlibs = dlibs->next;
1177 free (dlib_ptr);
1178 }
1179
1180 if (opt_chroot != NULL && dir_name != NULL)
1181 free (dir_name);
1182}
1183
1184/* Search through all libraries. */
1185static void
1186search_dirs (void)
1187{
1188 struct dir_entry *entry;
1189
1190 for (entry = dir_entries; entry != NULL; entry = entry->next)
1191 search_dir (entry);
1192
1193 /* Free all allocated memory. */
1194 while (dir_entries)
1195 {
1196 entry = dir_entries;
1197 dir_entries = dir_entries->next;
1198 free (entry->path);
1199 free (entry);
1200 }
1201}
1202
1203
1204static void parse_conf_include (const char *config_file, unsigned int lineno,
1205 bool do_chroot, const char *pattern);
1206
1207/* Parse configuration file. */
1208static void
1209parse_conf (const char *filename, bool do_chroot)
1210{
1211 FILE *file = NULL;
1212 char *line = NULL;
1213 const char *canon;
1214 size_t len = 0;
1215 unsigned int lineno;
1216
1217 if (do_chroot && opt_chroot)
1218 {
1219 canon = chroot_canon (opt_chroot, filename);
1220 if (canon)
1221 file = fopen (canon, "r");
1222 else
1223 canon = filename;
1224 }
1225 else
1226 {
1227 canon = filename;
1228 file = fopen (filename, "r");
1229 }
1230
1231 if (file == NULL)
1232 {
1233 if (errno != ENOENT)
1234 error (0, errno, _("\
1235Warning: ignoring configuration file that cannot be opened: %s"),
1236 canon);
1237 if (canon != filename)
1238 free ((char *) canon);
1239 return;
1240 }
1241
1242 /* No threads use this stream. */
1243 __fsetlocking (file, FSETLOCKING_BYCALLER);
1244
1245 if (canon != filename)
1246 free ((char *) canon);
1247
1248 lineno = 0;
1249 do
1250 {
1251 ssize_t n = getline (&line, &len, file);
1252 if (n < 0)
1253 break;
1254
1255 ++lineno;
1256 if (line[n - 1] == '\n')
1257 line[n - 1] = '\0';
1258
1259 /* Because the file format does not know any form of quoting we
1260 can search forward for the next '#' character and if found
1261 make it terminating the line. */
1262 *strchrnul (line, '#') = '\0';
1263
1264 /* Remove leading whitespace. NUL is no whitespace character. */
1265 char *cp = line;
1266 while (isspace (*cp))
1267 ++cp;
1268
1269 /* If the line is blank it is ignored. */
1270 if (cp[0] == '\0')
1271 continue;
1272
1273 if (!strncmp (cp, "include", 7) && isblank (cp[7]))
1274 {
1275 char *dir;
1276 cp += 8;
1277 while ((dir = strsep (&cp, " \t")) != NULL)
1278 if (dir[0] != '\0')
1279 parse_conf_include (filename, lineno, do_chroot, dir);
1280 }
1281 else if (!strncasecmp (cp, "hwcap", 5) && isblank (cp[5]))
1282 error (0, 0, _("%s:%u: hwcap directive ignored"), filename, lineno);
1283 else
1284 add_dir_1 (cp, filename, lineno);
1285 }
1286 while (!feof_unlocked (file));
1287
1288 /* Free buffer and close file. */
1289 free (line);
1290 fclose (file);
1291}
1292
1293/* Handle one word in an `include' line, a glob pattern of additional
1294 config files to read. */
1295static void
1296parse_conf_include (const char *config_file, unsigned int lineno,
1297 bool do_chroot, const char *pattern)
1298{
1299 if (opt_chroot != NULL && pattern[0] != '/')
1300 error (EXIT_FAILURE, 0,
1301 _("need absolute file name for configuration file when using -r"));
1302
1303 char *copy = NULL;
1304 if (pattern[0] != '/' && strchr (config_file, '/') != NULL)
1305 {
1306 if (asprintf (&copy, "%s/%s", dirname (strdupa (config_file)),
1307 pattern) < 0)
1308 error (EXIT_FAILURE, 0, _("memory exhausted"));
1309 pattern = copy;
1310 }
1311
1312 glob64_t gl;
1313 int result;
1314 if (do_chroot && opt_chroot)
1315 {
1316 char *canon = chroot_canon (opt_chroot, pattern);
1317 if (canon == NULL)
1318 return;
1319 result = glob64 (canon, 0, NULL, &gl);
1320 free (canon);
1321 }
1322 else
1323 result = glob64 (pattern, 0, NULL, &gl);
1324
1325 switch (result)
1326 {
1327 case 0:
1328 for (size_t i = 0; i < gl.gl_pathc; ++i)
1329 parse_conf (gl.gl_pathv[i], false);
1330 globfree64 (&gl);
1331 break;
1332
1333 case GLOB_NOMATCH:
1334 break;
1335
1336 case GLOB_NOSPACE:
1337 errno = ENOMEM;
1338 /* Fall through. */
1339 case GLOB_ABORTED:
1340 if (opt_verbose)
1341 error (0, errno, _("%s:%u: cannot read directory %s"),
1342 config_file, lineno, pattern);
1343 break;
1344
1345 default:
1346 abort ();
1347 break;
1348 }
1349
1350 free (copy);
1351}
1352
1353/* Honour LD_HWCAP_MASK. */
1354static void
1355set_hwcap (void)
1356{
1357 char *mask = getenv ("LD_HWCAP_MASK");
1358
1359 if (mask)
1360 hwcap_mask = strtoul (mask, NULL, 0);
1361}
1362
1363
1364int
1365main (int argc, char **argv)
1366{
1367 /* Set locale via LC_ALL. */
1368 setlocale (LC_ALL, "");
1369
1370 /* But keep the C collation. That way `include' directives using
1371 globbing patterns are processed in a locale-independent order. */
1372 setlocale (LC_COLLATE, "C");
1373
1374 /* Set the text message domain. */
1375 textdomain (_libc_intl_domainname);
1376
1377 /* Parse and process arguments. */
1378 int remaining;
1379 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
1380
1381 /* Remaining arguments are additional directories if opt_manual_link
1382 is not set. */
1383 if (remaining != argc && !opt_manual_link)
1384 {
1385 int i;
1386 for (i = remaining; i < argc; ++i)
1387 if (opt_build_cache && argv[i][0] != '/')
1388 error (EXIT_FAILURE, 0,
1389 _("relative path `%s' used to build cache"),
1390 argv[i]);
1391 else
1392 add_dir_1 (argv[i], "<cmdline>", 0);
1393 }
1394
1395 set_hwcap ();
1396
1397 if (opt_chroot != NULL)
1398 {
1399 /* Normalize the path a bit, we might need it for printing later. */
1400 char *endp = rawmemchr (opt_chroot, '\0');
1401 while (endp > opt_chroot && endp[-1] == '/')
1402 --endp;
1403 *endp = '\0';
1404 if (endp == opt_chroot)
1405 opt_chroot = NULL;
1406
1407 if (opt_chroot != NULL)
1408 {
1409 /* It is faster to use chroot if we can. */
1410 if (!chroot (opt_chroot))
1411 {
1412 if (chdir ("/"))
1413 error (EXIT_FAILURE, errno, _("Can't chdir to /"));
1414 opt_chroot = NULL;
1415 }
1416 }
1417 }
1418
1419 if (cache_file == NULL)
1420 {
1421 cache_file = alloca (strlen (LD_SO_CACHE) + 1);
1422 strcpy (cache_file, LD_SO_CACHE);
1423 }
1424
1425 if (config_file == NULL)
1426 config_file = LD_SO_CONF;
1427
1428 if (opt_print_cache)
1429 {
1430 if (opt_chroot != NULL)
1431 {
1432 char *p = chroot_canon (opt_chroot, cache_file);
1433 if (p == NULL)
1434 error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
1435 cache_file);
1436 cache_file = p;
1437 }
1438 print_cache (cache_file);
1439 if (opt_chroot != NULL)
1440 free (cache_file);
1441 exit (0);
1442 }
1443
1444 if (opt_chroot != NULL)
1445 {
1446 /* Canonicalize the directory name of cache_file, not cache_file,
1447 because we'll rename a temporary cache file to it. */
1448 char *p = strrchr (cache_file, '/');
1449 char *canon = chroot_canon (opt_chroot,
1450 p ? (*p = '\0', cache_file) : "/");
1451
1452 if (canon == NULL)
1453 error (EXIT_FAILURE, errno,
1454 _("Can't open cache file directory %s\n"),
1455 p ? cache_file : "/");
1456
1457 if (p)
1458 ++p;
1459 else
1460 p = cache_file;
1461
1462 cache_file = alloca (strlen (canon) + strlen (p) + 2);
1463 sprintf (cache_file, "%s/%s", canon, p);
1464 free (canon);
1465 }
1466
1467 if (opt_manual_link)
1468 {
1469 /* Link all given libraries manually. */
1470 int i;
1471
1472 for (i = remaining; i < argc; ++i)
1473 manual_link (argv[i]);
1474
1475 exit (0);
1476 }
1477
1478
1479 if (opt_build_cache)
1480 init_cache ();
1481
1482 if (!opt_only_cline)
1483 {
1484 parse_conf (config_file, true);
1485
1486 /* Always add the standard search paths. */
1487 add_system_dir (SLIBDIR);
1488 if (strcmp (SLIBDIR, LIBDIR))
1489 add_system_dir (LIBDIR);
1490 }
1491
1492 const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
1493 if (opt_chroot != NULL)
1494 aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
1495
1496 if (! opt_ignore_aux_cache && aux_cache_file)
1497 load_aux_cache (aux_cache_file);
1498 else
1499 init_aux_cache ();
1500
1501 search_dirs ();
1502
1503 if (opt_build_cache)
1504 {
1505 save_cache (cache_file);
1506 if (aux_cache_file)
1507 save_aux_cache (aux_cache_file);
1508 }
1509
1510 return 0;
1511}
1512