Changing Search Paths with crle(1) - they are a replacement |
Rod Evans Wednesday October 04, 2006
A developer who wished to add /usr/sfw/lib
to their default
runtime search path, managed to turn their system into a brick by using
crle(1):
# crle -l /usr/sfw/lib # ls ld.so.1: ls: fatal: libsec.so.1: open failed: No such file or directory Killed
The problem was that
crle(1),in this basic form, created a system wide configuration file.
This configuration file defined that the default runtime search path for
shared object dependencies is /usr/sfw/lib
. This search
path definition had replaced the standard defaults.
You can determine the standard search path defaults using crle(1).For example, without any system wide configuration file, the following defaults might exist:
$ crle Default configuration file (/var/ld/ld.config) not found Platform: 32-bit LSB 80386 Default Library Path (ELF): /lib:/usr/lib (system default) Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default)
This user had effectively removed the system default search paths, and hence the runtime linker, ld.so.1,had been unable to find the basic dependencies required by all applications. The new configuration file revealed:
$ crle Configuration file [version 4]: /var/ld/ld.config Platform: 32-bit LSB 80386 Default Library Path (ELF): /usr/sfw/lib Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default) Command line: crle -c /var/ld/ld.config -l /usr/sfw/lib
The -l
option allows you to define new search paths. However,
rather than dictate that a new search path definition be prepended, inserted,
or appended to any existing search paths,
crle(1)
simply replaces any existing search paths. The man page spells this out
in some detail:
-l dir .... Use of this option replaces the default search path. Therefore, a -l option is normally required to specify the original system default in relation to any new paths that are being applied. ....
Therefore, to prepend the new search path to the existing defaults you should specify each search path:
# crle -l /usr/sfw/lib -l /lib -l /usr/lib # ls devices/ lib/ proc/ ....
An alternative is to use the -u
, update, option.
Any new search paths supplied with
crle(1)
are appended to any existing search paths. Even if an existing
configuration file does not exist, the -u
option causes
any new search paths to be appended to the system defaults:
# crle -u -l /usr/sfw/lib # crle Configuration file [version 4]: /var/ld/ld.config Platform: 32-bit LSB 80386 Default Library Path (ELF): /lib:/usr/lib:/usr/sfw/lib Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default) Command line: crle -c /var/ld/ld.config -l /lib:/usr/lib:/usr/sfw/lib
Note that the usage message from crle(1) is a little misleading, as it implies that the new search path is an addition:
# crle -X crle: illegal option -- X .... [-l dir] add default search directory ....
We'll get the usage message updated to be more precise.
Remember, should you ever get in trouble with
crle(1)
configuration files, you can always instruct the runtime linker to
ignore processing the configuration file by setting the environment
variable LD_NOCONFIG=yes
:
# crle -l /does/not/exist # ls ld.so.1: ls: fatal: libsec.so.1: open failed: No such file or directory Killed # LD_NOCONFIG=yes ls devices/ lib/ proc/ .... # LD_NOCONFIG=yes rm /var/ld/ld.config # ls devices/ lib/ proc/ ....
It is recommended that when creating a new configuration file, you first
create the file in a temporary location. The environment variable
LD_CONFIG
can then be set to this new configuration file.
Refer to the
crle(1)
man page for an example.
Note. crle(1) should not be crippled by blowing away the system default search paths:
# crle -l /does/not/exist # crle Configuration file [version 4]: /var/ld/ld.config Platform: 32-bit MSB SPARC Default Library Path (ELF): /does/not/exist Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default) Command line: crle -c /var/ld/ld.config -l /does/not/exist # elfdump -d /usr/bin/crle | fgrep RPATH ld.so.1: fgrep: fatal: libc.so.1: open failed: No such file or directory ksh: 18184 Killed # LD_NOCONFIG=yes; export LD_NOCONFIG # elfdump -d /usr/bin/crle | fgrep RPATH [6] RPATH 0x61b $ORIGIN/../lib
Using $ORIGIN within a runpath provides crle(1) with a level of protection against insufficient configuration file information.
Note that it \*is\* possible to un-brickify a box in this state... Boot single-user, make sure /var is mounted read-write then zero out the config file:-
# > /var/ld/ld.config
At least that worked prior to Solaris 10... Now that /sbin/sh is dynamically linked I'm not so sure.
[22] Wrong ELF Class | [24] specifying a version binding |