c14176b6b8
for configuring NFS for a fail-over configuration with shared state. (bnc#689622) - rpc.mountd-segfault-fix; fix possible segfault caused by "showmount -e" usage. (bnc#693189) - do-not-error-when-address-family-not-supported - suppress socket error when IPv6 is not loaded (bnc#670449) - addmntent.fix - error check writes to /etc/mtab and cope accordingly. (bnc#689799) - mount-catch-signals - don't abort on SIGXSFZ or other signals while mtab is locked (bnc#689799) - mountd-auth-fix - fix bug that could give away incorrect access to NFS exported filesystems. (bnc#701702) OBS-URL: https://build.opensuse.org/package/show/Base:System/nfs-utils?expand=0&rev=52
111 lines
3.8 KiB
Plaintext
111 lines
3.8 KiB
Plaintext
From b50ad13298b3e9519a9bdecb8c146c9ecf39cef8 Mon Sep 17 00:00:00 2001
|
|
From: Jeff Layton <jlayton@redhat.com>
|
|
Date: Wed, 22 Jun 2011 14:51:38 -0400
|
|
Subject: [PATCH] nfs: fix host_reliable_addrinfo
|
|
References: bnc#701702
|
|
|
|
According to Neil Brown:
|
|
|
|
The point of the word 'reliable' is to check that the name we get
|
|
really does belong to the host in question - ie that both the
|
|
forward and reverse maps agree.
|
|
|
|
But the new code doesn't do that check at all. Rather it simply
|
|
maps the address to a name, then discards the address and maps the
|
|
name back to a list of addresses and uses that list of addresses as
|
|
"where the request came from" for permission checking.
|
|
|
|
This bug is exploitable via the following scenario and could allow an
|
|
attacker access to data that they shouldn't be able to access.
|
|
|
|
Suppose you export a filesystem to some subnet or FQDN and also to a
|
|
wildcard or netgroup, and I know the details of this (maybe
|
|
showmount -e tells me) Suppose further that I can get IP packets to
|
|
your server..
|
|
|
|
Then I create a reverse mapping for my ipaddress to a domain that I
|
|
own, say "black.hat.org", and a forward mapping from that domain to
|
|
my IP address, and one of your IP addresses.
|
|
|
|
Then I try to mount your filesystem. The IP address gets correctly
|
|
mapped to "black.hat.org" and then mapped to both my IP address and
|
|
your IP address.
|
|
|
|
Then you search through all of your exports and find that one of the
|
|
addresses: yours - is allowed to access the filesystem.
|
|
|
|
So you create an export based on the addrinfo you have which allows
|
|
my IP address the same access as your IP address.
|
|
|
|
Fix this by instead using the forward lookup of the hostname just to
|
|
verify that the original address is in the list. Then do a numeric
|
|
lookup using the address and stick the hostname in the ai_canonname.
|
|
|
|
Reviewed-by: NeilBrown <neilb@suse.de>
|
|
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
---
|
|
support/export/hostname.c | 36 ++++++++++++++++++++++++++++++------
|
|
1 file changed, 30 insertions(+), 6 deletions(-)
|
|
|
|
--- nfs-utils-1.2.3.orig/support/export/hostname.c
|
|
+++ nfs-utils-1.2.3/support/export/hostname.c
|
|
@@ -262,17 +262,19 @@ host_canonname(const struct sockaddr *sa
|
|
* @sap: pointer to socket address to look up
|
|
*
|
|
* Reverse and forward lookups are performed to ensure the address has
|
|
- * proper forward and reverse mappings.
|
|
+ * matching forward and reverse mappings.
|
|
*
|
|
- * Returns address info structure with ai_canonname filled in, or NULL
|
|
- * if no information is available for @sap. Caller must free the returned
|
|
- * structure with freeaddrinfo(3).
|
|
+ * Returns addrinfo structure with just the provided address with
|
|
+ * ai_canonname filled in. If there is a problem with resolution or
|
|
+ * the resolved records don't match up properly then it returns NULL
|
|
+ *
|
|
+ * Caller must free the returned structure with freeaddrinfo(3).
|
|
*/
|
|
__attribute_malloc__
|
|
struct addrinfo *
|
|
host_reliable_addrinfo(const struct sockaddr *sap)
|
|
{
|
|
- struct addrinfo *ai;
|
|
+ struct addrinfo *ai, *a;
|
|
char *hostname;
|
|
|
|
hostname = host_canonname(sap);
|
|
@@ -280,9 +282,31 @@ host_reliable_addrinfo(const struct sock
|
|
return NULL;
|
|
|
|
ai = host_addrinfo(hostname);
|
|
+ if (!ai)
|
|
+ goto out_free_hostname;
|
|
|
|
- free(hostname);
|
|
+ /* make sure there's a matching address in the list */
|
|
+ for (a = ai; a; a = a->ai_next)
|
|
+ if (nfs_compare_sockaddr(a->ai_addr, sap))
|
|
+ break;
|
|
+
|
|
+ freeaddrinfo(ai);
|
|
+ if (!a)
|
|
+ goto out_free_hostname;
|
|
+
|
|
+ /* get addrinfo with just the original address */
|
|
+ ai = host_numeric_addrinfo(sap);
|
|
+ if (!ai)
|
|
+ goto out_free_hostname;
|
|
+
|
|
+ /* and populate its ai_canonname field */
|
|
+ free(ai->ai_canonname);
|
|
+ ai->ai_canonname = hostname;
|
|
return ai;
|
|
+
|
|
+out_free_hostname:
|
|
+ free(hostname);
|
|
+ return NULL;
|
|
}
|
|
|
|
/**
|