3

Here is written that curlftpfs is terribly slow because of bug in newest libcurl3-gnutls. Downgrading is not recommended due to large reverse dependencies that this package has (can be verified via apt-cache showpkg libcurl3-gnutls:amd64 or apt-cache rdepends libcurl3-gnutls:amd64). So I've decided to downgrade it different way. I've checked available versions in repository:

$ apt-cache policy libcurl3-gnutls:amd64
libcurl3-gnutls:
  Installed: 7.43.0-1ubuntu2.1
  Candidate: 7.43.0-1ubuntu2.1
  Version table:
 *** 7.43.0-1ubuntu2.1 0
        500 http://sk.archive.ubuntu.com/ubuntu/ wily-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu/ wily-security/main amd64 Packages
        100 /var/lib/dpkg/status
     7.43.0-1ubuntu2 0
        500 http://sk.archive.ubuntu.com/ubuntu/ wily/main amd64 Packages

Then I've downloaded and extracted older version than installed one:

$ apt-get install -d libcurl3-gnutls=7.43.0-1ubuntu2
$ sudo mv /var/cache/apt/archives/libcurl3-gnutls_7.43.0-1ubuntu2_amd64.deb .
$ dpkg -x libcurl3-gnutls_7.43.0-1ubuntu2_amd64.deb  extracted_deb

Then I've backed up original binary and searched for some common name in shared libraries:

$ cp $(which curlftpfs) .
$ ldd ./curlftpfs | grep curl
        libcurl-gnutls.so.4 => /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 (0x00007fcac4443000)

$ readelf -d ./curlftpfs  | grep -i curl
 0x0000000000000001 (NEEDED)             Shared library: [libcurl-gnutls.so.4]

Following step was just the proof that linked file belongs exactly to libcurl3-gnutls package and that curlftpfs depends on libcurl3-gnutls:

$ dpkg -S /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4
libcurl3-gnutls:amd64: /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4

$ apt-cache depends curlftpfs
curlftpfs
  Depends: libc6
  Depends: libcurl3-gnutls
  Depends: libfuse2
  Depends: libglib2.0-0
  Depends: fuse
  Conflicts: curlftpfs:i386

Also the content of extracted and installed libcurl3-gnutls package seems exactly the same:

$ dpkg -L libcurl3-gnutls:amd64 | sort
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.3
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4
/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.3.0
/usr/share
/usr/share/doc
/usr/share/doc/libcurl3-gnutls
/usr/share/doc/libcurl3-gnutls/changelog.Debian.gz
/usr/share/doc/libcurl3-gnutls/copyright
/usr/share/doc/libcurl3-gnutls/NEWS.Debian.gz
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/libcurl3-gnutls

$ find extracted_deb/ | sort
extracted/
extracted/usr
extracted/usr/lib
extracted/usr/lib/x86_64-linux-gnu
extracted/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.3
extracted/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4
extracted/usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.3.0
extracted/usr/share
extracted/usr/share/doc
extracted/usr/share/doc/libcurl3-gnutls
extracted/usr/share/doc/libcurl3-gnutls/changelog.Debian.gz
extracted/usr/share/doc/libcurl3-gnutls/copyright
extracted/usr/share/doc/libcurl3-gnutls/NEWS.Debian.gz
extracted/usr/share/lintian
extracted/usr/share/lintian/overrides
extracted/usr/share/lintian/overrides/libcurl3-gnutls

My question is how can I rewrite the path that is contained in ldd output and point it to file that I've extracted? I've read about rpath and patchelf and chrpath here and here but I guess this is not my case because following commands returns nothing useful:

$ readelf -d ./curlftpfs | grep -i rpath
$
$ chrpath -l ./curlftpfs
./curlftpfs: no rpath or runpath tag found.
$
$ patchelf --print-rpath ./curlftpfs
$

So it seems that rpath is not used. I've also read about $LD_LIBRARY_PRELOAD but I guess that it will change path for all shared libraries for given binary not just one particular (in my case /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4) so I would need to have whole tree of libraries. There is also solutions which suggest changing loader (in my example /lib64/ld-linux-x86-64.so.2 I guess):

$ patchelf --print-interpreter ./curlftpfs 
/lib64/ld-linux-x86-64.so.2
$
$ ldd ./curlftpfs | grep ld-linux
    /lib64/ld-linux-x86-64.so.2 (0x0000564966b64000)
$
$ ls -laL /lib/x86_64-linux-gnu/ld-2.21.so
-rwxr-xr-x 1 root root 154376 Mar 26  2015 /lib/x86_64-linux-gnu/ld-2.21.so

but to be honest I didn't get the point of this. Can you please assists?

1 Answer 1

0

My question is how can I rewrite the path that is contained in ldd output and point it to file that I've extracted?

It seems like what you want is to override the functionality for just the libcurl-gnutls.so library with an older version. As hinted to in the last link you provided, you can use the LD_PRELOAD environment variable to override the standard library functions.

Say your manually installed (downgraded) version of libcurl-gnutls has the dynamic library file /usr/local/lib/libcurl-gnutls.so.4.4.0. You could then do something like the following: LD_PRELOAD=/usr/local/lib/libcurl-gnutls.so.4.4.0 curlftpfs [some_arguments...]

Don't forget that /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 and /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.3 are just symbolic links to the master library file for libcurl-gnutls. Copying these symbolic links may not have the desired effect. You need the long named SO file, like libcurl-gnutls.so.4.4.0 .

Extra Notes

You can test that this override worked by doing something like the following: LD_PRELOAD=/usr/local/lib/libcurl-gnutls.so.4.4.0 ldd $(which curlftpfs)

For a manual installation, /usr/local/lib may not be a good place to put a dynamic library that you don't want interfering with other binaries. This is because /etc/ld.so.conf.d/libc.conf may point to /usr/local/lib for automatic libraries. (My Debian machine does)

To see the definitions of the LD_ environment variable, check out the ld.so(8) man page (man ld.so).

5
  • Thank you for reply. One question is this changing one particular library? In this case /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4. Would be also possible to somehow modify binary to point to this library? Thank you. Commented Mar 27, 2016 at 19:19
  • This would effectively be changing this one particular library, since it will override all/primary functions provided by the original library. In this case it would override libcurl-gnutls.so.4, if curlftpfs was compiled to use that library. I suspect there should be a clever way to rewrite a binary's linking information to use a different shared library name, but I currently do not posses that knowledge. As a manual hack, you could try using a hex editor and change the text that specifies libcurl-gnutls.so.4 to maybe libcurl-gnutls.so.2 (probably should be same length name).
    – Craig H
    Commented Mar 28, 2016 at 4:35
  • Honestly, if you are thinking about modifying the curlftpfs binary, you should probably just compile curlftpfs by hand and change the dependencies.
    – Craig H
    Commented Mar 28, 2016 at 4:44
  • Of course I can but I was mainly interested in some reverse engineering approach Commented Mar 29, 2016 at 4:42
  • Alright, then, as previously mentioned, you can rename the library dependency inside the binary using a hex editor like Bless. I just tried it with the ls binary. Just open the hex editor on the curlftpfs binary. Search for libcurl-gnutls.so.4 text. Rename the file inline, while maintaining the original length. If you need more detail, I can write another answer.
    – Craig H
    Commented Mar 29, 2016 at 22:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.