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