3

This command is doing the rounds for detecting currently running processes using glibc:

lsof | grep libc | awk '{print $2}' | sort | uniq

I find it intensely annoying, since /libc/ matches not only libc, but on my system:

/lib/x86_64-linux-gnu/libcap.so.2.24
/lib/x86_64-linux-gnu/libcgmanager.so.0.0.0
/lib/x86_64-linux-gnu/libcom_err.so.2.1
/lib/x86_64-linux-gnu/libcrypt-2.19.so
/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
/usr/lib/libcamel-1.2.so.45.0.0
/usr/lib/unity-settings-daemon-1.0/libcolor.so
/usr/lib/unity-settings-daemon-1.0/libcursor.so
/usr/lib/x86_64-linux-gnu/colord-plugins/libcd_plugin_camera.so
/usr/lib/x86_64-linux-gnu/colord-plugins/libcd_plugin_scanner.so
/usr/lib/x86_64-linux-gnu/gtk-3.0/modules/libcanberra-gtk3-module.so
/usr/lib/x86_64-linux-gnu/libcairo-gobject.so.2.11301.0
/usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0
/usr/lib/x86_64-linux-gnu/libcanberra-0.30/libcanberra-pulse.so
/usr/lib/x86_64-linux-gnu/libcanberra-gtk3.so.0.1.9
/usr/lib/x86_64-linux-gnu/libcanberra.so.0.2.5
/usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
/usr/lib/x86_64-linux-gnu/libck-connector.so.0.0.0
/usr/lib/x86_64-linux-gnu/libcolordprivate.so.1.0.23
/usr/lib/x86_64-linux-gnu/libcolord.so.1.0.23
/usr/lib/x86_64-linux-gnu/libcroco-0.6.so.3.0.1
/usr/lib/x86_64-linux-gnu/libcupsmime.so.1
/usr/lib/x86_64-linux-gnu/libcups.so.2
/usr/lib/x86_64-linux-gnu/samba/libcliauth.so.0
/usr/lib/x86_64-linux-gnu/samba/libcli_cldap.so.0
/usr/lib/x86_64-linux-gnu/samba/libcli-ldap-common.so.0
/usr/lib/x86_64-linux-gnu/samba/libcli-nbt.so.0
/usr/lib/x86_64-linux-gnu/samba/libcli_smb_common.so.0
/usr/lib/x86_64-linux-gnu/samba/libcli_spoolss.so.0
/usr/lib/x86_64-linux-gnu/samba/liblibcli_lsa3.so.0
/usr/lib/x86_64-linux-gnu/samba/liblibcli_netlogon3.so.0

I understand that libc is used by pretty much everything, but I'd like to refine this command. Consider its applications for other libraries. How can I do this?

The flaw in this approach, in my opinion, is that the package providing libc may include a whole host of other shared library files (all of which may or may not be covered under the umbrella term that is the library name, like glibc, or libboost-python). Using a word boundary or - to mark the end of libc doesn't really fix this. This may not be a flaw, perhaps, as Braiam points out, since many or all of these .so files may link to a core file in which the flaw resides, as is the case for libc6 on Debian.

If a specific OS/distro is needed, assume Debian Linux.

Also annoying is that this command could be condensed to lsof | awk '/libc/{print $2}' | sort -u.

muru
  • 69,900
  • 13
  • 192
  • 292
  • 1
    Use `grep -w libc`. Or the `awk` that was added at the end – roaima Jan 28 '15 at 23:33
  • @roaima interesting. While that would work with libc, it might fail for some other libraries, since some use `_` in their name. – muru Jan 28 '15 at 23:41
  • I also considered `libc-`, but then I wondered if that's the only shared library from the libc package. – muru Jan 28 '15 at 23:43
  • Personally I went for the reboot approach earlier this evening. With something as fundamental as libc being affected I couldn't guarantee I'd caught everything. "Emergency maintenance" can be a wonderful catch-all. – roaima Jan 28 '15 at 23:45
  • @roaima [I know](http://askubuntu.com/a/578582/158442). But I'd like to know a good way to track which processes use a give library package. – muru Jan 28 '15 at 23:47
  • `lsof` seems as good a method as any. Or statically `ldd`. For matching you need to play with regular expressions. `grep '/libc-'` works here, but if you wanted to find something like `libcan` you could use something like `'/libcan\>'`, where the `\>` forces a match on _end of word_. – roaima Jan 28 '15 at 23:52
  • I believe `lsof | grep 'libc[^[:alpha:]]*.so'` should match everything as you expect, including `libc6` and the like. – jimmij Jan 29 '15 at 00:06
  • Now I think naming libc in the question was a bad idea. It inspired the question, but I was really hoping for a more general approach. – muru Jan 29 '15 at 00:11
  • How about `fuser /path/to/the-libc-shared-object` ? – Mark Plotnick Jan 29 '15 at 01:45

3 Answers3

4

That's a roundabout and grossly inaccurate method. You know the location of the library file, so you don't need to use heuristics to match it, you can search for the exact path.

There's a very simple way to list the processes have a file open:

fuser /lib/x86_64-linux-gnu/libc.so.6

However this lists the processes that have the current version of the file open, i.e. the processes that use the new copy of the library. If you want to list the processes that have the deleted copy, you can use lsof, but searching for an exact path. Restrict lsof to the filesystem containing the deleted file for performance (and possibly to avoid blocking on e.g. temporarily inaccessible network filesystems).

lsof -o / | awk '$4 == "DEL" && $8 == "/lib/x86_64-linux-gnu/libc-2.13.so" {print $2}'

If the upgraded package contains several libraries and you want to detect any of the libraries, list all the library files from the package. Here's a way to do it programmatically (for a Debian package, adjust according to your distribution, e.g. rpm -ql glibc on Red Hat).

lsof -o / | awk '
   BEGIN {
       while (("dpkg -L libc6:amd64 | grep \\\\.so\\$" | getline) > 0)
           libs[$0] = 1
   }
   $4 == "DEL" && $8 in libs {print $2}'
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • Beautiful! I was tending towards `lsof $(dpkg -L libc6 | grep .so$)` myself, but was unsure if I missed anything, which I did. I take it that awk loop runs thus: process command once, and the loop runs getline over till output lasts? – muru Jan 30 '15 at 01:33
  • @muru Yes, the `BEGIN` block is executed once whereas the rest of the awk script is executed once per output line. The while-getline loop runs the command “piped” into getline just once, and getline returns its output a line at a time. An empty line marks the end of the piped command. – Gilles 'SO- stop being evil' Jan 30 '15 at 06:11
1

Use grep -w libc in this instance. You can also use ldd for static analysis.

For matching you need to play with regular expressions. grep '/libc-' works here, but if you wanted to find something like libcan you could use something like '/libcan\>', where the \> forces a match on end of word.

roaima
  • 107,089
  • 14
  • 139
  • 261
  • Since neither answer was upvoted yet, I chose to edit the question, broadening it. Can you have a look at the update? – muru Jan 29 '15 at 00:18
  • @muru To find additionally something like`libc6` can use `grep -w 'libc[0-9]*'` – Costas Jan 29 '15 at 01:50
-1

To test GHOST vulnerability (everything found before us):

wget https://gist.githubusercontent.com/koelling/ef9b2b9d0be6d6dbab63/raw/de1730049198c64eaf8f8ab015a3c8b23b63fd34/gistfile1.c
gcc gistfile1.c -o CVE-2015-0235
./CVE-2015-0235

Source

Costas
  • 14,806
  • 20
  • 36