Bug 458676 (CVE-2008-4552)

Summary: CVE-2008-4552 nfs-utils: incorrect use of tcp_wrappers, causing hostname-based rules to be ignored
Product: [Other] Security Response Reporter: Josh Bressers <bressers>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: dkovalsk, herrold, jscotka, kreilly, michele.marcionelli, osoukup, redhat-bugzilla, steved, tao, thoger
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2010-02-19 13:57:13 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:
Bug Depends On: 494585, 494878    
Bug Blocks:    

Description Josh Bressers 2008-08-11 14:55:29 UTC
It seems that tcp_wrappers does not honor netgroups.  As this was noted in a different unrelated bug, I'm opening this one:
https://bugzilla.redhat.com/show_bug.cgi?id=440114#c8

    It seems that netgroups are not working; if I put in my hosts.allow file

    mountd: hostname
    - or -
    mountd: ip-address

    then I can mount, but if I have a netgroup, I can't... for instance

    mountd: @selected_hosts

    Can you confirm this behaviour?

Comment 1 Josh Bressers 2008-08-11 14:57:19 UTC
Jan,

Can you verify this?  I lack the proper expertise and infrastructure to test this bug.

Comment 3 Jan Safranek 2008-08-20 14:13:07 UTC
Sorry for the delay... debugging this is just painful.

It seems to be fixed in recent nfs-utils (I checked ver. 1.1.3), the RHEL-5 one passes arguments to tcp_wrappers in wrong order:

--- nfs-utils-1.0.9/support/misc/tcpwrapper.c	2006-07-08 02:04:32.000000000 +0200
+++ nfs-utils-1.1.3/support/misc/tcpwrapper.c	2008-07-27 23:01:45.000000000 +0200
@@ -124,12 +125,12 @@
 	   return 0;
 
    /* Check the official name first. */
-   if (hosts_ctl(daemon, "", hp->h_name, ""))
+   if (hosts_ctl(daemon, hp->h_name, "", ""))
 	return 1;
 
    /* Check aliases. */
    for (sp = hp->h_aliases; *sp ; sp++) {
-	if (hosts_ctl(daemon, "", *sp, ""))
+	if (hosts_ctl(daemon, *sp, "", ""))
 	    return 1;
    }
 

BTW, during my investigation I noticed that portmap is linked with tcp_wrappers statically, without any obvious reason. This makes the debugging even harder :(.

Comment 4 Josh Bressers 2008-08-20 18:46:13 UTC
It appears this bug goes all the way back to RHEL2

Comment 5 Josh Bressers 2008-10-13 15:06:43 UTC
I'm moving this to the Security Response product for proper tracking.

Comment 6 Tomas Hoger 2008-10-15 09:19:12 UTC
CVE id CVE-2008-4552 was assigned to this issue:

nfs-utils 1.0.9, and possibly other versions before 1.1.3, invokes the
host_ctl function with the wrong order of arguments, which causes TCP
Wrappers to ignore netgroups and allows remote attackers to bypass
intended access restrictions.

Comment 7 Steve Dickson 2008-12-04 20:21:17 UTC
I believe this is fixed... see Comment #6

Comment 8 Tomas Hoger 2009-03-27 16:22:50 UTC
(In reply to comment #0)
> It seems that tcp_wrappers does not honor netgroups.  As this was noted in a
> different unrelated bug, I'm opening this one:
> https://bugzilla.redhat.com/show_bug.cgi?id=440114#c8

This should not be limited to netgroups.  Any hostname-based rule was ignored due to this problem with incorrect tcp_wrappers API usage.


(In reply to comment #7)
> I believe this is fixed... see Comment #6  

I believe this refers to comment #6 in (private) bug #440120m which mentions patch proposed by Jan in this bug in comment #3 has been added to the nfs-utils-1.0.9-40.el5, which got released in Red Hat Enterprise Linux 5.3 via RHBA-2009:0107.

Though that fix does not fully resolve the problem.  good_client function in nfs-utils calls hosts_access repeatedly, returning success whenever hosts_ctl returns "allow" reply, first passing it only IP address, secondly passing it only hostname, and later all aliases (if any).

This approach does not work correctly when hostname-based rule is specified in hosts.deny.  If hosts.deny contains e.g.:

  service: .evildomain.com

This rule will be ignored during the first hosts_ctl call, as no hostname is provided to hosts_ctl, only IP address.  If there's no other rule for that IP, hosts_ctl returns allow and good_client exists with success.  hosts_ctl call for hostname is not reached.

The final solution seems to be the full rewrite of the good_client Steve recently did for Fedora - see bug #480223.  good_client now looks like:

int
good_client(daemon, addr)
char *daemon;
struct sockaddr_in *addr;
{
    struct request_info req;

    request_init(&req, RQ_DAEMON, daemon, RQ_CLIENT_SIN, addr, 0);
    sock_methods(&req);

    if (hosts_access(&req))
        return ALLOW;

    return DENY;
}

Steve, have there been any problem reported for this rewrite?

Comment 9 Tomas Hoger 2009-04-03 10:32:36 UTC
Rewrite of good_client in Steve's git:

http://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commitdiff;h=ae8e7dbe9641dbc69c34bcede416f0d91612d3f1

Comment 10 Tomas Hoger 2009-04-03 13:27:29 UTC
There is one possible "drawback" of this rewrite - host aliases will not be usable in hosts access rules.  Actually, without the patch in comment #3, they are not usable anyway, as any other hostname.  tcp_wrappers do not attempt to handle aliases at all, so proper handling of alias is probably not what one should expect form any application using tcp_wrappers.

This not handling of alias should only affect rules like:

hosts.allow:
  service: some-alias

hosts.deny:
  service: ALL

It only seems to be possible to define those aliases in /etc/hosts (or equivalent host map), it does not seem to affect cases when IP has multiple PTR records, as only one name is returned when resolving IP.

Most obvious case when this may be an issue is localhost.  Installer sets localhost.localdomain as a canonical name by default, localhost only being an alias.  Therefore, rule 'service: localhost' may be impacted.  This case has already been worked-around, see bug #196326.  Additionally, in nfs-utils case, all local access is allowed regardless of the tcp_wrappers config.

Comment 11 Tomas Hoger 2009-04-06 15:47:14 UTC
(In reply to comment #8)
> This approach does work correctly when hostname-based rule is specified in
> hosts.deny.  If hosts.deny contains e.g.:
> 
>   service: .evildomain.com

There is at least one another case where patch in comment #3 is not sufficient, not even requiring hostname-based rule.  Let's assume mostly-open setup, where only some subnet should have access denied (similar to the example in comment #8, only using network/netmask):

hosts.deny:
  service: 10.0.0.0/255.0.0.0

For client connecting from 10/8, first call to hosts_ctl would return DENY, subsequent call to hosts_ctl with hostname set but IP "" would return ALLOW, resulting in ALLOW returned by good_client.

Comment 16 errata-xmlrpc 2009-09-02 10:02:53 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 5

Via RHSA-2009:1321 https://rhn.redhat.com/errata/RHSA-2009-1321.html

Comment 19 Tomas Hoger 2010-02-19 13:57:13 UTC
This was fixed in Red Hat Enterprise Linux 5 (in 5.4) and 4 (in 4.8).  Red Hat Enterprise Linux 3 is not affected (not using libwrap).