Red Hat Bugzilla – Bug 12442
rpc.statd runs as root
Last modified: 2014-03-16 22:14:21 EDT
And it doesn't really need to. Chris Evans <email@example.com> has
a patch to fix this.
If it's considered overkill for it to have its own account, perhaps it
could share a generic "rpc" userid with portmap and others?
Eww.. well Daniel J has finally posted to Bugtraq confirming that it is
remote-root exploitable. Debian have issued a security update.
I'll attach my chroot(), non-root patch for rpc.statd. However it is almost
certainly too high a risk to use in a security update. Maybe Rawhide! (next on
the depriv list is telnetd, incidentally)
Created attachment 1248 [details]
Runs rpc.statd under its own user, and chroot()'ed. Very untested!!!!
Patch makes future rpc.statd holes much much much less useful to attackers.
Because of the chroot(), the non-root shell is very hard to upgrade to a root
Issues with patch
- Very untested. rpc.statd starts up (with correct security credentials and raw
socket) but I haven't verified correct operation. I'm not too familair with
- Requires new user/group"rpcstatd"
- Requires new directory /var/lib/nfs/rpcstatd, which must be owned by rpcstatd
- Maybe more. Needs review.
I consider the best way to progress Linux security is in the form of damage
limitation patches like this one (things like capabilities and even MAC are just
a form of containment/damage limitation). Because of this, consider this patch
actively supported if any issues are found with it ;-)
This defect is considered MUST-FIX for Winston Beta-5
Changed responsibility for this defect, per Erik's request (and Bill's
Will be fixed in nfs-utils-1.9.1-3.
(make that 1.9.1-4)
Patch seems to have been lost in BETA5 version, 0.1.9.1-5 :-(
This is a shame - the patch is "high risk" so it would have been nice to make
the public beta.
Is it wise to delay this patch until RH7.1, or could it still receive adequate
testing in time for RH7.0? I guess I'd rather play safe than be responsible for
breaking a package in RH7.0!
Oh, crud, forgot to apply the patch. I'm all in favor
of leaving it in; what actually uses statd anyways?
Hmm.. I think statd is used to monitor nfs file locks. When an NFS client
reboots (perhaps due to a crash), it contacts statd which then clears out the
stale locks. Or something like that.
statd and lockd on the local machine communicate. Also, remote clients contact
Disclaimer: all the above might be complete BS ;-)
Anyway onto the issue of "to patch or not to patch". Are you in a position to
reapply the patch and check new S(RPMS) into RawHide? I bet if you asked nicely
on testers-list, you could find a volunteer who knows they actively use statd
and would be willing to test a new package. What do you think?
Added in nfs-utils-0.1.9.1-6. Really. I had to
move the initgroups() before the chroot(); or else
it segfaulted. It worked to the extent that I could
lock a file over NFS. Dunno how much more testing you
Sorry about the segfault! That sounds like a glibc-2.2 bug to me, though,
Note that I now favour not bothering with initgroups(), and using setgroups(0,
NULL) instead. In fact you'll be receiving the telnetd patch soon which uses
rpc.statd from nfs-utils-0.1.9.1-7 is still segfaulting:
open("/usr/lib/libnss_dns.so.2", O_RDONLY) = -1 ENOENT (No such file or
stat("/usr/lib", 0xbffff000) = -1 ENOENT (No such file or directory)
--- SIGSEGV (Segmentation fault) ---
Backing out the drop-privs patch makes the segfault goes away but obviously has
other bad effects. ;-)
Really? Does it do this repeatedly for you?
(It works OK here...)
This defect has been re-classified as SHOULD-FIX for Winston Gold-release
Rats. Tim, got a reproducable testcase?
What versions of glibc are involved here?
In fact, is the segfault occuring within statd or glibc?
Could be another glibc segfault - glibc 2.1.9x is very non-robust in a chroot()
environment compared with 2.1.2.
This happens every time.
I'll attach the ltrace output. It's happening in the C library..
Created attachment 2585 [details]
ltrace -f /sbin/rpc.statd
What are you using for NSS (normal? NIS? ldap? kerberos?)?
With 'hosts: files' it works fine. With 'hosts: files dns' it segfaults.
/etc/hosts just has localhost.
Can anyone but me reproduce this?
Haven't had a chance to check yet. :(
Works for me (glibc-2.1.92-8, nfs-utils-0.1.9.1-7).
Fails for me too. So far, I have tried the following combinations at the NFS
server (the client that counts in this case is still running 6.2):
nfs-utils-0.1.9.1-7, glibc-2.1.92-5: rpc.statd SEGVs.
nfs-utils-0.2-2, glibc-2.1.92-5: rpc.statd SEGVs.
nfs-utils-0.2-2, glibc-2.1.92-14: rpc.statd appears to run but doesn't actually
do anything; I get "lockd: cannot monitor 000.111.222.333" when a client
attempts to lock anything.
nfs-utils-0.1.9.1-7 with the drop-privs patch backed out, either glibc: WORKS.
So I'm back to a statd without the fix, since non-working NFS locking means my
mail folders don't work --- it's a bit of a showstopper.
Whats the RH7.0 released versions status?
If it's still bust, give me a localhost-only test case (if possible) and it'll
Hmm - the tendency for glibc-2.2 to segfault in a chroot() environment is
worrying. glibc-2.1 didn't use to do that for me.
The RH7.0 shipped versions (nfs-utils-0.1.9.1-7, glibc-2.1.92-14) still fails.
One thing I found which easily reproduced the "rpc.statd just doesn't run" is
having /var/lib/nfs/statd not owned by rpcuser.rpcuser, but even with that
working, it Just Doesn't Work, giving the above message "lockd: cannot monitor
xxx.." on any remote locking attempt.
I'll attach an ltrace output of the broken rpc.statd failing to permit a lock.
"odo.scot.redhat.com" is the server concerned, and "184.108.40.206" is the
client trying to obtain the lock. The rpc.statd tries to gethostbyname() on
both the server's full hostname and the client's IP address, fails on both
(because /etc is missing --- no surprise there), and bombs with a syslog of
syslog(5, "%s", "STAT_FAIL to odo.scot.redhat.com for SM_MON of 220.127.116.11")
If rpc.statd is relying on hostname conversions, then it's hardly something that
can legally run in a chrooted environment. Looking at the source in
utils/statd/monitor.c, if RESTRICTED_STATD isn't defined (and I can't see it
defined anywhere) then we have
* Check hostnames. If I can't look them up, I won't monitor. This
* might not be legal, but it adds a little bit of safety and sanity.
D'oh. I think I see the problem. Just *where* are we expecting to see these
hostnames from in the chrooted environment?
Created attachment 3566 [details]
ltrace output of statd failing to monitor a client
In glibc-2.1, (RH6.2), the call
would initialize the resolver system and cache filehandles to /etc/host.conf,
/etc/hosts, open a network connection to the name server, etc.
This would leave the resolver happy within a chroot().
I'll get the glibc update (in case it makes any difference) and see what's up.
I haven't downloaded the glibc update yet, but I see the release notes claim
that a segfault
in gethostbyname() under certain conditions is fixed. Can anyone with the glibc
still get rpc.statd to segfault?
I can't any more.
OK, closing as fixed in the glibc errata.
Stephen - does statd now Work For You (tm) with the glibc update?
If not please re-open.
Well, my statd seems happy to resolve hostnames. And that's _without_ the glibc
If anyone can still reproduce non-working NFS locking, please let me know, and
- strace() of failure (to highlight which files we need to open/cache before the
- details of name resolution, e.g. /etc/nsswitch.conf, /etc/resolv.conf,
- (especially details of any of these files which are not stock RH7.0)
Ah, one more comment
the sethostent(1) call seems to read in
/etc/resolv.conf, /etc/hosts, /etc/nsswitch.conf
but it fails to look at
If anyone can reproduce failure, I'd be grateful if they could try this patch
It forces a gethostbyaddr() call which makes sure all resolver files are opened.
As a minor bonus extra, tzset() is called to make sure the chroot() environment
has the correct time locale set up, for e.g. syslog() messages.
--- statd.c.old Mon Oct 23 07:16:52 2000
+++ statd.c Mon Oct 23 07:17:24 2000
@@ -162,6 +162,9 @@
* trying to open /etc/* for the dozenth time
/* Drop privs */
OK, the new glibc seems to work, but the more I think about it, the more I am
convinced that the whole thing is still broken. I'm reopening this bug to get
some feedback on it. Can we please back-out the chroot environment altogether?
Face it, hostname resolution inside a chroot sandbox DOES NOT WORK.
You can cache the initial resolver state at first, sure, but what happens if:
/etc/hosts, /etc/resolv.conf or /etc/host.conf
get overwritten? What about the NIS server binding in
being updated? The NIS binding files are dynamic --- ypbind deletes them on
loss of contact with the server and recreates them on rebind, so just having a
handle on the old file descriptor does NOT work.
The chroot environment passes the "OK, it boots" test but will result in an
unreliable service if you start adding hosts to the network and connecting new
hostnames to a running NFS server.
Eww. Damn hostname resolution.
Well, if we do decide to revert the chroot(), we should _definitely_ keep the rest of
the patch, which runs rpc.statd as non-root.
Note that the YP argument is probably valid, assuming the nis code opens
The /etc/hosts, /etc/resolv.conf, /etc/host.conf agument would seem bogus
though, because glibc AFAIK caches the contents _once_. I don't believe
changing them will affect running processes, regardless of whether they are
chroot()'ed or not.
This is currently resolved with statd running as non-root, non-chrooted()
(too many problems with the chroot.)