- nfs.init,nfsserver.init,sysconfig.nfs - Add support

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
This commit is contained in:
Neil Brown 2011-06-23 05:52:18 +00:00 committed by Git OBS Bridge
parent 5660cc2acd
commit c14176b6b8
10 changed files with 391 additions and 10 deletions

52
addmntent.fix Normal file
View File

@ -0,0 +1,52 @@
From a47739bf3b89432e112d1d2ed9bbdaf1e09d450a Mon Sep 17 00:00:00 2001
From: Neil Brown <neilb@suse.de>
Date: Tue, 17 May 2011 14:36:21 +1000
Subject: [PATCH] Remove risk of nfs_addmntent corrupting mtab
nfs_addmntent is used to append directly to /etc/mtab.
If the write partially fail, e.g. due to RLIMIT_FSIZE,
truncate back to original size and return an error.
See also https://bugzilla.redhat.com/show_bug.cgi?id=697975
(CVE-2011-1749) CVE-2011-1749 nfs-utils: mount.nfs fails to anticipate RLIMIT_FSIZE
Signed-off-by: NeilBrown <neilb@suse.de>
---
support/nfs/nfs_mntent.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- nfs-utils-1.2.1.orig/support/nfs/nfs_mntent.c
+++ nfs-utils-1.2.1/support/nfs/nfs_mntent.c
@@ -12,6 +12,7 @@
#include <string.h> /* for index */
#include <ctype.h> /* for isdigit */
#include <sys/stat.h> /* for umask */
+#include <unistd.h> /* for ftruncate */
#include "nfs_mntent.h"
#include "nls.h"
@@ -127,9 +128,11 @@ int
nfs_addmntent (mntFILE *mfp, struct mntent *mnt) {
char *m1, *m2, *m3, *m4;
int res;
+ off_t length;
if (fseek (mfp->mntent_fp, 0, SEEK_END))
return 1; /* failure */
+ length = ftell(mfp->mntent_fp);
m1 = mangle(mnt->mnt_fsname);
m2 = mangle(mnt->mnt_dir);
@@ -143,6 +146,12 @@ nfs_addmntent (mntFILE *mfp, struct mnte
free(m2);
free(m3);
free(m4);
+ if (res >= 0)
+ res = fflush(mfp->mntent_fp);
+ if (res < 0)
+ /* Avoid leaving a corrupt mtab file */
+ ftruncate(fileno(mfp->mntent_fp), length);
+
return (res < 0) ? 1 : 0;
}

View File

@ -0,0 +1,38 @@
From: Suresh Jayaraman <sjayaraman@suse.de>
Subject: [PATCH] supress socket error when address family is not supported
Patch-mainline: No
References: bnc#670449
It was observed that when ipv6 module was not loaded and cannot be auto-loaded,
when starting NFS server, the following error occurs:
"rpc.nfsd: unable to create inet6 TCP socket: errno 97 (Address
family not supported by protocol)"
This is obviously a true message, but does not represent an "error" when ipv6
is not enabled. Rather, it is an expected condition. As such, it can be
confusing / misleading / distracting to display it in this scenario.
This patch instead of throwing error when a socket call fails with
EAFNOSUPPORT, makes it as a NOTICE.
Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
utils/nfsd/nfssvc.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- nfs-utils-1.2.1.orig/utils/nfsd/nfssvc.c
+++ nfs-utils-1.2.1/utils/nfsd/nfssvc.c
@@ -137,7 +137,12 @@ nfssvc_setfds(const struct addrinfo *hin
sockfd = socket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol);
if (sockfd < 0) {
- xlog(L_ERROR, "unable to create %s %s socket: "
+ if (errno == EAFNOSUPPORT)
+ xlog(L_NOTICE, "address family %s not "
+ "supported by protocol %s",
+ family, proto);
+ else
+ xlog(L_ERROR, "unable to create %s %s socket: "
"errno %d (%m)", family, proto, errno);
rc = errno;
goto error;

83
mount-catch-signals Normal file
View File

@ -0,0 +1,83 @@
Subject: [PATCH] mount: improve signal management when locking mtab.
References: bnc#689799
As mount.nfs can run setuid it must be careful about how the user can
interact with in. In particular it needs to ensure it does not
respond badly to any signals that the user might be able to generate.
This is particularly an issue while updating /etc/mtab (when that is
not linked to /proc/mounts). If the user can generate a signal which
kills mount.nfs while /etc/mtab is locked, then it will leave the file
locked, and could possibly corrupt mtab (particularly if 'ulimit 1'
was previously issued).
Currently lock_mtab does set some handlers for signals, but not
enough. It arranges for every signal up to (but not including)
SIGCHLD to cause mount.nfs to unlock mdadm promptly exit ... even if
the default behaviour would be to ignore the signal. SIGALRM is
handled specially, and signals after SIGCHLD are left with their
default behaviour. This includes for example SIGXFSZ which can be
generated by the user running "ulimit 1".
So: change this so that some signals are left unchanged, SIGALRM is
handled as required, and all signals that the user can generate are
explicitly ignored.
The remainder still cause mount.nfs to print a message, unlock mtab, and exit.
Signed-off-by: NeilBrown <neilb@suse.de>
---
utils/mount/fstab.c | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
--- nfs-utils-1.2.1.orig/utils/mount/fstab.c
+++ nfs-utils-1.2.1/utils/mount/fstab.c
@@ -331,16 +331,43 @@ lock_mtab (void) {
int sig = 0;
struct sigaction sa;
- sa.sa_handler = handler;
sa.sa_flags = 0;
sigfillset (&sa.sa_mask);
- while (sigismember (&sa.sa_mask, ++sig) != -1
- && sig != SIGCHLD) {
- if (sig == SIGALRM)
+ while (sigismember (&sa.sa_mask, ++sig) != -1) {
+ switch(sig) {
+ case SIGCHLD:
+ case SIGKILL:
+ case SIGCONT:
+ case SIGSTOP:
+ /* These cannot be caught, or should not,
+ * so don't even try.
+ */
+ continue;
+ case SIGALRM:
sa.sa_handler = setlkw_timeout;
- else
+ break;
+ case SIGHUP:
+ case SIGINT:
+ case SIGQUIT:
+ case SIGWINCH:
+ case SIGTSTP:
+ case SIGTTIN:
+ case SIGTTOU:
+ case SIGPIPE:
+ case SIGXFSZ:
+ case SIGXCPU:
+ /* non-priv user can cause these to be
+ * generated, so ignore them.
+ */
+ sa.sa_handler = SIG_IGN;
+ break;
+ default:
+ /* The rest should not be possible, so just
+ * print a message and unlock mtab.
+ */
sa.sa_handler = handler;
+ }
sigaction (sig, &sa, (struct sigaction *) 0);
}
signals_have_been_setup = 1;

110
mountd-auth-fix Normal file
View File

@ -0,0 +1,110 @@
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;
}
/**

View File

@ -1,3 +1,21 @@
-------------------------------------------------------------------
Thu Jun 23 05:41:25 UTC 2011 - nfbrown@novell.com
- nfs.init,nfsserver.init,sysconfig.nfs - Add support
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)
-------------------------------------------------------------------
Fri Jun 17 14:12:19 UTC 2011 - aj@suse.de

View File

@ -56,6 +56,11 @@ Patch2: nfs-utils-clear-mountd-reg
Patch3: nfs-utils-allow-port-number-sharing
Patch4: nfs-utils-improve-v4-umount
Patch5: nfs-utils-fix-remount
Patch6: rpc.mountd-segfault-fix
Patch7: do-not-error-when-address-family-not-supported
Patch8: addmntent.fix
Patch9: mount-catch-signals
Patch10: mountd-auth-fix
Suggests: python-base
%description
@ -139,6 +144,11 @@ Authors:
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
cp %{S:6} .
%build

View File

@ -32,6 +32,10 @@ STATD_BIN=/usr/sbin/rpc.statd
IDMAPD_CLIENT_STATE=/var/run/nfs/nfs-rpc.idmapd
IDMAPD_SERVER_STATE=/var/run/nfs/nfsserver-rpc.idmapd
if [ -z "$RPC_PIPEFS_DIR" ]; then
RPC_PIPEFS_DIR=/var/lib/nfs/rpc_pipefs
fi
NEED_IDMAPD=no
NEED_GSSD=no
NEED_LDCONFIG=no
@ -116,18 +120,18 @@ fi
mount_rpc_pipefs() {
# See if the file system is there yet
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs` in
case `stat -c "%t" -f "$RPC_PIPEFS_DIR"` in
*67596969*)
return 0;;
esac
mount -t rpc_pipefs rpc_pipefs /var/lib/nfs/rpc_pipefs
mount -t rpc_pipefs rpc_pipefs "$RPC_PIPEFS_DIR"
}
umount_rpc_pipefs() {
# See if the file system is there
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs` in
case `stat -c "%t" -f "$RPC_PIPEFS_DIR"` in
*67596969*)
umount /var/lib/nfs/rpc_pipefs
umount "$RPC_PIPEFS_DIR"
esac
}

View File

@ -79,6 +79,10 @@ if [ "$NFS4_SUPPORT" = yes ]; then
NEED_IDMAPD=yes
fi
if [ -z "$RPC_PIPEFS_DIR" ]; then
RPC_PIPEFS_DIR=/var/lib/nfs/rpc_pipefs
fi
check_for_nfsdfs() {
HAVE_NFSDFS="no"
while read dummy type ; do
@ -117,19 +121,19 @@ nfs4_unbind_mounts() {
mount_rpc_pipefs() {
# See if the file system is there yet
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs` in
case `stat -c "%t" -f "$RPC_PIPEFS_DIR"` in
*67596969*)
return 0;;
esac
mount -t rpc_pipefs rpc_pipefs /var/lib/nfs/rpc_pipefs
mount -t rpc_pipefs rpc_pipefs "$RPC_PIPEFS_DIR"
}
umount_rpc_pipefs() {
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs` in
case `stat -c "%t" -f "$RPC_PIPEFS_DIR"` in
*67596969*)
umount /var/lib/nfs/rpc_pipefs;;
umount "$RPC_PIPEFS_DIR";;
esac
}
@ -139,7 +143,7 @@ do_start_svcgssd() {
done
mount_rpc_pipefs
startproc $SVCGSSD_BIN
startproc $SVCGSSD_BIN $SVCGSSD_OPTIONS
return $?
}
@ -232,7 +236,7 @@ case "$1" in
fi
# rpc.nfsd
echo -n " nfsd"
$NFSD_BIN $PARAMS $VERSION_PARAMS || {
$NFSD_BIN $NFSD_OPTIONS $PARAMS $VERSION_PARAMS || {
rc_status -v
rc_exit
}

30
rpc.mountd-segfault-fix Normal file
View File

@ -0,0 +1,30 @@
From 730f6986f86873513fa021a450eb55ccd0f2fbff Mon Sep 17 00:00:00 2001
From: Steve Dickson <steved@redhat.com>
Date: Wed, 26 Jan 2011 07:49:19 -0500
Subject: [PATCH] Fixed segfault in rpc.mountd
A unallocated piece of memory, instead of a NULL point, was being
used to initialize a ->next point in the mount link list which
caused a segfault after a few remote accesses via the showmount
command.
Signed-off-by: Steve Dickson <steved@redhat.com>
---
utils/mountd/rmtab.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index d339296..527377f 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -205,6 +205,7 @@ mountlist_list(void)
}
if (stb.st_mtime != last_mtime) {
mountlist_freeall(mlist);
+ mlist = NULL;
last_mtime = stb.st_mtime;
setrmtabent("r");
--
1.7.3.4

View File

@ -100,3 +100,35 @@ STATD_OPTIONS=""
# in a fail-over configuration with all clients on well connected
# low latency links.
NFSV4LEASETIME=""
## Path: Network/File systems/NFS server
## Description: Alternate mount point for rpc_pipefs filesystem
## Type: string
## Default: ""
#
# In a high-availabilty configuration it is possible that /var/lib/nfs
# is redirected so some shared storage and so it is not convenient to
# mount the rpc_pipefs filesystem at /var/lib/nfs/rpc_pipefs. In that
# case an alternate mount point can be given here.
RPC_PIPEFS_DIR=""
## Path: Network/File systems/NFS server
## Description: Options for svcgssd
## Type: string
## Default: ""
#
# Normally svcgssd does not require any option. However in a
# high-availabilty configuration it can be useful to pass "-n"
# to guide the choice of default credential. To allow for that
# case or any other requiring options ot svcgssd, they can
# be specified here.
SVCGSSD_OPTIONS=""
## Path: Network/File systems/NFS server
## Description: Extra options for nfsd
## Type: string
## Default: ""
#
# This setting allows extra options to be specified for NFSD, such as
# -H <shared_hostname> in a high-availability configuration.
NFSD_OPTIONS=""