15

I've tried a python application on my CentOS machine and it gives me the following error:

ImportError: /usr/lib64/libc.so.6: version `GLIBC_2.18' not found (required by /tmp/_MEI2BYIr4/libstdc++.so.6)

I've been tempted to upgrade GLIBC, but after having read some forums it seems I could break the system. Do you know any alternative?

Thanks

Paco el Cuqui
  • 199
  • 1
  • 1
  • 8
  • it seems already dubious to have libstdc++ in /tmp/ . Was it done by the python application? – A.B Jan 29 '18 at 17:52
  • 2
    There is no reason for any legitimate Python application to have placed a copy of a system C/C++ library under `/tmp`. Contact its developer and make sure you got a correct and clean copy of the program, and ensure that your system does not have malware now. – Michael Hampton Jan 29 '18 at 22:23
  • @MichaelHampton Believe it or not, this looks like it's legit. The exact same path appears in a Github issue related to a bioinformatics tool: https://github.com/BioinformaticsFMRP/TCGAbiolinks/issues/162#issuecomment-360149428 –  Jan 30 '18 at 06:01
  • @duskwuff OK, that's a little bizarre. What on earth do they think they're doing? – Michael Hampton Jan 30 '18 at 17:51
  • @MichaelHampton Scientists, man. As long as the research gets done… –  Jan 30 '18 at 18:30
  • Hi @MichaelHampton, I'm in fact the guy stuck with that bioinformatics tool. – Paco el Cuqui Jan 31 '18 at 08:39

4 Answers4

19

Check it is actually needed

Firstly check the python application as it could be out of date and is probably misreading the glibc version. CentOS shows the base version as installed and is patched to keep up with changes and it could just be a case of fixing the version that is being looked for in the code as a quick fix, but if the application is being actively developed you need to let the developers know or fork it for yourself if you can.

An up to date glibc on CentOS 7 should be 2.17-196.el7_4.2

If it is needed, Containerise

If it's absolutely necessary to run this application, the official RHEL approach would be to containerize, but you would still need to provide a working glibc, which wouldn't be possible with stock CentOS 7.

As a last resort, install glibc in a nonstandard location

If this isn't viable, and as an absolute last resort, it is possible to install a newer version of glibc than 2.18 as that is 9 years old now and glibc has been updated for several vulnerabilities and I'm not sure off the top of my head if it will build with the version of make in CentOS 7, but any newer version should work as follows:

  • This can potentially affect the functionality of your computer so make sure you know what you are doing

You can build the version of glibc you require elsewhere on your server and add it to LD_LIBRARY_PATH for the application. Note this must only be done for the application only.

wget http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
tar zxvf glibc-2.18.tar.gz
cd glibc-2.18
mkdir build
cd build
../configure --prefix=/opt/glibc-2.18
make -j4
sudo make install

Then to run a binary you need to use patchelf to update its interpreter

patchelf --set-interpreter /opt/glibc-2.18/lib/ld-linux-x86-64.so.2 program_you_are_running

And you need to enable it to find the new glibc library, either by

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/glibc-2.18/lib

Or you can use patchelf to update the binary's rpath (you can combine this with the previous pathelf command)

patchelf --set-rpath /opt/glibc-2.18/lib:/usr/lib64 program_you_are_running

If you change LD_LIBRARY_PATH don't export it for the whole system because all the binaries unmodified by patchelf will segfault.

/opt is the standard place to install third-party applications and libraries but you can use any path away from the system paths.

Timmmm
  • 1,514
  • 2
  • 11
  • 16
Simon Greenwood
  • 1,343
  • 9
  • 12
  • 1
    This is really bad advice. glibc is not an ordinary library; installing it under a nonstandard path is likely to make the system unbootable. –  Jan 30 '18 at 03:52
  • 1
    @duskwuff why, when it is only being called from an environment being set up to run this particular application? – Simon Greenwood Jan 30 '18 at 08:07
  • glibc includes boot-critical components like `ld.so`, and installing it may write configuration files to global locations like `/etc/ld.so.conf`. –  Jan 30 '18 at 19:45
  • 1
    It doesn't if you build it with `--prefix` as I specified there. It's not a good solution but it works if it's unavoidable. I updated my answer with other options and that should really be a last resort. – Simon Greenwood Jan 30 '18 at 19:51
  • 2
    This is kind of the right answer, but it's also extremely dangerous. I don't think that's stressed enough here. We spent years in the late 1990s and early 2000s dealing with broken systems when people tried to upgrade glibc in place. If one isn't careful, one might accidentally replace system glibc with a different version and cause a broken system. – Michael Hampton Jan 30 '18 at 20:30
  • @MichaelHampton I agree, also with your observation above (in fact the code behaviour is familiar from something I've built recently but can't remember what) and I'd try and restrict as much as I could but there are cases for doing it and it's not something to do lightly. – Simon Greenwood Jan 30 '18 at 20:49
  • 1
    I've tried this option and in the end, when I export LD_LIBRARY_PATH, no command works. – Paco el Cuqui Jan 31 '18 at 08:40
  • @PacoelCuqui updated the answer, my mistake. However, please look at the first part of the answer as building an external glibc is the absolute last resort. – Simon Greenwood Jan 31 '18 at 09:12
  • 8
    Absolutely nothing wrong with installing libraries in a _NON-standard_ path. The problem here is _exporting_ LD_LIBRARY_PATH, which as @PacoelCuqui found, breaks everything, because then ALL programs run by any shell with the export use the new libc. The trick is to not export LD_LIBRARY_PATH but to place it on the command line ahead of the only the binaries which need it: `$ LD_LIBRARY_PATH=/opt/glibc-2.18/lib my_special_program`. A complication here is that it must be used before `python prog.py` which means Python also runs with the new libc - which could be a problem. – duanev Jan 16 '19 at 19:51
  • "Containerize"- I understand that, but how would you update its glibc. Would you do the "last resort" in the standard location? That protects the host system but would it muck up the apps within the container? – Robert Lugg Jul 30 '19 at 20:42
  • Unfortunately I found the same as @PacoelCuqui - if I compile a more modern glibc and add it to `LD_LIBRARY_PATH` then every command just segfaults. – Timmmm Aug 12 '21 at 21:07
  • Ah you have to update the interpreter as in Mark's answer. I'll update this one. – Timmmm Aug 13 '21 at 08:33
3

In the end,I did not have to upgrade GLIBC. The gdc-client tool I downloaded through R seemed to be for Ubuntu and not CentOS, though I did it on CentOS 7. I then downloaded the gdc-client for CentOS and it worked fine.

Paco el Cuqui
  • 199
  • 1
  • 1
  • 8
3

On CentOS 7, I included the /usr/lib64 folder in the rpath as follows

patchelf --set-interpreter /opt/glibc-2.18/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.18/lib:/usr/lib64 pydio-agent

This worked for me

kenlukas
  • 2,886
  • 2
  • 14
  • 25
0

I use patchelf --set-interpreter /opt/glibc-2.18/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.18/lib:/usr/lib64 ./clangd, but it doesn't work. It still reports ./clangd: /lib64/libc.so.6: version GLIBC_2.18' not found (required by ./clangd)`.

$ ldd ./clangd
./clangd: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by ./clangd)
        linux-vdso.so.1 =>  (0x00007ffd15ffe000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd74d2e5000)
        librt.so.1 => /lib64/librt.so.1 (0x00007fd74d0dd000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fd74ced9000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fd74cbd7000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fd74c809000)
        /home/harriszh/.local/glibc2.18/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fd74d501000)

The issue is as shown above. ld.so still is pointed to system's one.

if I use the following command, it works.

/home/harriszh/.local/glibc2.18/lib/ld-linux-x86-64.so.2 --library-path /home/harriszh/.local/glibc2.18/lib ./clangd

Do you know how to correct patchelf's issue?

harriszh
  • 1
  • 1