Bug 464886

Summary: denyhosts requires selinux policy changes to work without disabling other critical services like NFS
Product: Red Hat Enterprise Linux 5 Reporter: jonathan
Component: selinux-policy-targetedAssignee: Daniel Walsh <dwalsh>
Status: CLOSED ERRATA QA Contact: BaseOS QE <qe-baseos-auto>
Severity: medium Docs Contact:
Priority: medium    
Version: 5.2CC: dwalsh, mmalik
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-01-20 21:31:00 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
bash script to find programs using tcp_wrappers none

Description jonathan 2008-10-01 01:54:57 UTC
Description of problem:

When denyhosts purges the /etc/hosts.deny file it creates a temporary file
/etc/hosts.deny.purge.tmp which it edits and then renames to /etc/hosts.deny
This new file has a selinux label applied of "user_u:object_r:etc_runtime_t:s0"
applied since it is a file created at runtime by a daemon without any special
selinux policy. 

The fact that a new file in /etc/ has the etc_runtime_t label is correct as
that prevents other daemons from reading a file that might have been created or
modified by an untrusted process, however, denyhosts has to do this to operate
correctly and when it edits the file all of the other daemons which need to
read the /etc/hosts.deny (as they enforce tcpwrappers policy as well) can not
read the file and incorrectly deny service to valid clients.

This includes critical services like:

NFS (used for sharing filesystems)

and 

tftp (used to install systems)

and maybe others. This makes using denyhosts out of the box with an enforcing
selinux install impossible. 

I've seen a similar bug #212771 reported in bugzilla in 2006 and closed early
2008 without any fix as

https://bugzilla.redhat.com/show_bug.cgi?id=212771

I also reported this to the denyhosts package in Fedora-Extras and they included a plugin I provided as a partial fix, but suggested this needed to be reported to the upstream selinux policy for RHEL, as what denyhosts is trying to do requires is difficult with the past way the policy is defined in /etc but might be much easier with some new selinux policy capabilities that are being worked on now for future rhel releases. Some discussion of this can be seen in the links below. 

This bug can be seen at:

https://bugzilla.redhat.com/show_bug.cgi?id=463191

This issue, however, goes beyond just the den

The solutions I've seen in some discussion of this problem on email lists
include:

Best: Write a selinux policy for denyhosts that allows it to edit and set the
the /etc/hosts.deny file to a special type, and modify the policy of other
daemons that need to access it so they also have access to that new type.

To avoid race conditions the temporary file needs to be created in the
denyhosts code with the right type (or it might be possible for the policy type
transistion rules to set it correctly at creation)

https://www.redhat.com/archives/fedora-selinux-list/2007-September/msg00077.html

https://www.redhat.com/archives/fedora-selinux-list/2007-September/msg00071.html

Current work-around/solution: I wrote a denyhosts plugin that is called
whenever the "purge" operation is done. The plugin just calls "restorecon" on
the /etc/hosts.deny* files after the purge occurs so the files are changed back
to "etc_t" type files and thus can be read by other programs.

This is not a completely correct solution as there is a race condition while
the purge file is being created and renamed and before the "plugin" is executed
-- but I would guess it's a small window. 


Version-Release number of selected component (if
applicable):denyhosts-2.6-5.el5


How reproducible:

Any system using selinux in enforcing mode, denyhosts, nfs (or tftp) and
waiting at least 4 weeks (the default PURGE time in the default denyhosts.conf
that is installed by the rpm) should experience the problem.

Steps to Reproduce:
1.
2.
3.

Actual results:

nfs.mountd and tftp refuse any access to the services and log an error that they failed to read /etc/hosts.deny 

Expected results:

They allow service for authorized clients.

Comment 1 Daniel Walsh 2008-10-01 12:02:17 UTC
Which nfs daemon are you seeing a denial for?

Currently nfsd_t can read etc_runtime_t.

I can modify tftpd_t to read it also.

Do you know of other confined domains that use /etc/denyhosts.conf?

I think writing policy for denyhosts would not be a bad idea since this is a fairly dangerous application,  It reads random log content and then acts on it.

But not likely for RHEL5.

The restorecon solution is a good one for now.  Other scripts that create mislabeled files do this and the race condition, is unlikely to fire.

Comment 2 jonathan 2008-10-01 13:50:47 UTC
A policy for denyhosts would be great, but I understand there are limits to what can be included in the current release series. 

The messages I received for nfs were specifically for portmap. The /var/log/messages error was:

Sep 19 20:18:32 moose portmap[2691]: warning: cannot open /etc/hosts.deny: Permission denied

and the audit log was:
type=AVC msg=audit(1221869801.815:25684): avc:  denied  { read } for  pid=2691 comm="portmap" name=
"hosts.deny" dev=sda1 ino=2024197 scontext=system_u:system_r:portmap_t:s0 tcontext=root:object_r:et
c_runtime_t:s0 tclass=file

For the tftp case here is an audit log showing the denial. (of read and getattr)

type=AVC msg=audit(1221858396.393:25307): avc:  denied  { read } for  pid=26664 comm="in.tftpd" nam
e="hosts.deny" dev=sda1 ino=2024197 scontext=system_u:system_r:tftpd_t:s0-s0:c0.c1023 tcontext=root
:object_r:etc_runtime_t:s0 tclass=file

and 

audit.log.3:type=AVC msg=audit(1221858885.742:25346): avc:  denied  { getattr } for  pid=26951 comm
="in.tftpd" path="/etc/hosts.deny" dev=sda1 ino=2024197 scontext=system_u:system_r:tftpd_t:s0-s0:c0
.c1023 tcontext=root:object_r:etc_runtime_t:s0 tclass=file


As to your question about confined domains that use /etc/denyhosts.conf -- did you really mean /etc/denyhosts.conf, or did you mean /etc/hosts.deny?

For the first case I don't think anyone besides denyhosts uses it. 

For the second it should be accessed by any daemon using tcp_wrappers. Now some of those daemons may already have access (for example I was also running sshd and it did not have a problem accessing /etc/hosts.deny during this time) but I was not running most of them so I can't be sure. To get a quick idea of potential targets I ran the little shell script I wrote (find_libwrap.sh -- it's attached to this comment) to see what daemons in /usr/sbin/ use tcp_wrappers. The list of output from the script is below.

conmand
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x000000342b200000)
exim
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b64a43b0000)
exportfs
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b21d97b4000)
in.tftpd
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x000000342b200000)
mailstats
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b91a7068000)
makemap
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b3cc4c31000)
praliases
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002ae55c61a000)
rpc.mountd
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b78e2fe9000)
rpc.rquotad
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002ad99fda9000)
sendmail
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b6e01e0d000)
sendmail.exim
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b235c0eb000)
sendmail.sendmail
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002af4a6e72000)
ldd: warning: you do not have execution permission for `./smartd-conf.pyc'
ldd: warning: you do not have execution permission for `./smartd-conf.pyo'
smrsh
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b2f52b9a000)
snmpd
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b66f8268000)
snmptrapd
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b903d88e000)
sshd
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002ab19373b000)
stunnel
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002b1bbc07f000)
ldd: warning: you do not have execution permission for `./xenmon.pyc'
ldd: warning: you do not have execution permission for `./xenmon.pyo'
xinetd
	libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002ad4ce9a2000)

Comment 3 jonathan 2008-10-01 13:54:03 UTC
Created attachment 318196 [details]
bash script to find programs using tcp_wrappers

Comment 4 Daniel Walsh 2008-10-02 13:55:34 UTC
Fixed in selinux-policy-2.4.6-162.el5

Comment 9 errata-xmlrpc 2009-01-20 21:31:00 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2009-0163.html