Bug 159601 - ldconfig makes links point to wrong place?
Summary: ldconfig makes links point to wrong place?
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: rawhide
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Brian Brock
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2005-06-05 16:34 UTC by Jonathan Kamens
Modified: 2007-11-30 22:11 UTC (History)
0 users

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2005-06-13 16:03:36 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
output of strace after removing bad link (657.48 KB, text/plain)
2005-06-08 21:06 UTC, Jonathan Kamens
no flags Details

Description Jonathan Kamens 2005-06-05 16:34:07 UTC
I'm getting "rpm --verify" errors from openldap:

....L...    /usr/lib/liblber-2.2.so.7
....L...    /usr/lib/libldap-2.2.so.7
....L...    /usr/lib/libldap_r-2.2.so.7

All of these are pointing at the corresponding ".so" symlinks, e.g., liblber-
2.2.so.7 is pointing at liblber.so.  Removing the links and rerunning them 
causes them to once again point at the ".so" links.  I think they should be 
pointing at the "-2.2.so.7.0.19" files, which are (a) the canonical names and 
(b) real files rather than symlinks, instead.  I don't understand the logic of 
how ldconfig decides what to point links at enough to know why the wrong thing 
is happening.

Comment 1 Jakub Jelinek 2005-06-06 07:53:46 UTC
Can't reproduce it.
Can you please
ls -l /usr/lib/liblber*
for i in /usr/lib/liblber*; do echo -n $i ""; readelf -d $i | grep SONAME; done
rpm -qf /usr/lib/liblber*
?

Comment 2 Jonathan Kamens 2005-06-08 05:14:17 UTC
Script started on Wed 08 Jun 2005 01:13:04 AM EDT
jik2:/tmp!1000$ ls -l /usr/lib/liblber*
lrwxrwxrwx  1 root root    10 Jun  5 12:29 /usr/lib/liblber-2.2.so.7 -> liblber.so
-rwxr-xr-x  1 root root 54376 May 19 18:00 /usr/lib/liblber-2.2.so.7.0.19
-rw-r--r--  1 root root 84322 May 19 18:00 /usr/lib/liblber.a
lrwxrwxrwx  1 root root    21 Jun  4 22:41 /usr/lib/liblber.so ->
liblber-2.2.so.7.0.19
jik2:/tmp!1001$ for i in /usr/lib/liblber*; do echo -n $i ""; readelf -d $i |
grep SONA ME; done
/usr/lib/liblber-2.2.so.7  0x0000000e (SONAME)                     Library
soname: [liblber-2.2.so.7]
/usr/lib/liblber-2.2.so.7.0.19  0x0000000e (SONAME)                     Library
soname: [liblber-2.2.so.7]
/usr/lib/liblber.a /usr/lib/liblber.so  0x0000000e (SONAME)                    
Library soname: [liblber-2.2.so.7]
jik2:/tmp!1002$ rpm -qf /usr/lib/liblber*
openldap-2.2.26-1
openldap-2.2.26-1
openldap-devel-2.2.26-1
openldap-devel-2.2.26-1
jik2:/tmp!1003$ exit

Script done on Wed 08 Jun 2005 01:13:38 AM EDT


Comment 3 Jakub Jelinek 2005-06-08 08:23:25 UTC
readelf -d liblber-2.2.so.7.0.6 | grep SONAME; ls -l liblber*; strace -e symlink
/sbin/ldconfig -n .; ls -l
liblber*
 0x0000000e (SONAME)                     Library soname: [liblber-2.2.so.7]
lrwxrwxrwx  1 jakub jakub    20 Jun  8 10:06 liblber-2.2.so ->
liblber-2.2.so.7.0.6
-rwxr-xr-x  1 jakub jakub 47224 Aug 20  2004 liblber-2.2.so.7.0.6
-rwxr-xr-x  1 jakub jakub 71704 Sep 12  2004 liblber.a
symlink("liblber-2.2.so.7.0.6", "./liblber-2.2.so.7") = 0
lrwxrwxrwx  1 jakub jakub    20 Jun  8 10:06 liblber-2.2.so ->
liblber-2.2.so.7.0.6
lrwxrwxrwx  1 jakub jakub    20 Jun  8 10:09 liblber-2.2.so.7 ->
liblber-2.2.so.7.0.6
-rwxr-xr-x  1 jakub jakub 47224 Aug 20  2004 liblber-2.2.so.7.0.6
-rwxr-xr-x  1 jakub jakub 71704 Sep 12  2004 liblber.a

ldconfig.c does not attempt to create links to links:
      /* Don't create links to links.  */
      if (dlib_ptr->is_link == 0)
        create_links (dir_name, entry->path, dlib_ptr->name,
                      dlib_ptr->soname);

create_links is the only place in ldconfig that calls symlink syscall, and
it is only called from this place and manual_link, but manual_link is only for
ldconfig -l.
        if (__builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
...
      is_link = S_ISLNK (lstat_buf.st_mode);
...
      /* A link may just point to itself.  */
      if (is_link)
        {
          /* If the path the link points to isn't its soname and it is not
             .so symlink for ld(1) only, we treat it as a normal file.  */
          const char *real_base_name = basename (real_file_name);

          if (strcmp (real_base_name, soname) != 0)
            {
              len = strlen (real_base_name);
              if (len < strlen (".so")
                  || strcmp (real_base_name + len - strlen (".so"), ".so") != 0
                  || strncmp (real_base_name, soname, len) != 0)
                is_link = 0;
            }
        }
...
                  dlib_ptr->is_link = is_link;

So I really don't see how the behaviour you are seeing is possible.
Please rm /usr/lib/liblber-2.2.so.7 and post strace /sbin/ldconfig.

Comment 4 Jonathan Kamens 2005-06-08 21:06:20 UTC
Created attachment 115240 [details]
output of strace after removing bad link

Comment 5 Jakub Jelinek 2005-06-13 16:03:36 UTC
Oh, the important thing is that liblber.so has different prefix from
liblber-2.2.so.7, so the is_link = 0 does trigger (while in my test I was
using liblber-2.2.so and in that case the link will point to
liblber-2.2.so.7.0.*).

The above hunk is really needed for weirdo library naming schemes other libraries
are using and the way openldap calls its libraries is really non-standard.

Furthermore, unless you remove by hand the liblber-2.2.so.7 symlink rpm creates
when installing openldap package, ldconfig should not change that symlink
to liblber.so (even if it sees liblber.so symlink first, if liblber-2.2.so.7
points to liblber-2.2.so.7.0.19 and liblber.so to that file as well prior to
running ldconfig, ldconfig will see with stat that it already points to the
desired dev/ino and will not change it).  So I don't think anything needs
changing.


Note You need to log in before you can comment on or make changes to this bug.