Search code examples
linuxlinkerpingldstrace

Why ping does work from user, but does not work as root? Why root cannot load existing libraries, while user can?


I discovered, that ping works when run as user, but does not work when beeing root. The problem is, that when beeing root, LD does not load /lib64/libnss_dns.so.2 library, it gets EACCESS error.

When i run ping from root:

root# ping -c1 localhost
ping: unknown host localhost

This is because:

root# strace ping -c1 localhost 
....
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
open("/lib64/tls/x86_64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
stat("/lib64/tls/x86_64", 0x7fffa619da70) = -1 EACCES (Permission denied)
open("/lib64/tls/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
stat("/lib64/tls", 0x7fffa619da70)      = -1 EACCES (Permission denied)
open("/lib64/x86_64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
stat("/lib64/x86_64", 0x7fffa619da70)   = -1 EACCES (Permission denied)
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = -1 EACCES (Permission denied)
stat("/lib64", {st_mode=S_IFDIR|0655, st_size=4096, ...}) = 0

No worries. /lib64/libnss_files.so.2 exists in my system:

# ls -la /lib64/libnss_files.so.2
lrwxrwxrwx 1 root root 20 2015-08-19  /lib64/libnss_files.so.2 -> libnss_files-2.15.so
$ ls -la /lib64/libnss_files-2.15.so 
-rwxr-xr-x 1 root root 62418 2012-07-16  /lib64/libnss_files-2.15.so

And ping works perfecly fine when run as user:

user# ping -c1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.038 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.038/0.038/0.038/0.000 ms
user# strace ping -c1 localhost
...
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
...

If I do LD_PRELOAD libnss_files.so.2, then ping works from root (Why?) :

root# LD_PRELOAD=/lib64/libnss_files.so.2 ping -c1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.043 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.043/0.043/0.043/0.000 ms

This systems ping has setuid:

# ls -la /usr/bin/ping
-rwsr-sr-x 1 root root 40000 2012-07-16  /usr/bin/ping

How is that possible? Why does root gets EACCES error when loading libraries, while user loads them without a problem? Why does LD_PRELOAD has an effect on a binary with setuid? Does LD_PRELOAD has an effect on a binary with setuid if it is run from root?

I have script-recorded the output of LD_DEBUG=all ping -c1 localhost and strace -f ping -c1 localhost runned from user and root available here:

script.user.txt

script.root.txt

System is relatively old:

# uname -a
Linux gucio 3.4.6-2.10-desktop #1 SMP PREEMPT Thu Jul 26 09:36:26 UTC 2012 (641c197) x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/SuSE-release
openSUSE 12.2 (x86_64)
VERSION = 12.2
CODENAME = Mantis
$ ping -V
ping utility, iputils-sss20101006

There is no SELinux in this system. There is AppArmor in this system.


Solution

  • The accepted answer of https://serverfault.com/questions/747784/ping-as-root-doesnt-work-with-hostname-but-with-ip-normal-user-works suggests that there may be a problem with the permissions of / (or /lib64). In that case the x privilege was missing for owner on /, and a chmod +x / solved the problems.

    Maybe your system suffers from the same permission problems?