Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Feb 2012 16:22:34 GMT
From:      Attila Bogár <attila.bogar@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/164933: [nfs] [patch] mountd(8) drops mixed security flavors for multiple lines per same share
Message-ID:  <201202091622.q19GMY3h091558@red.freebsd.org>
Resent-Message-ID: <201202091630.q19GU91I032652@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         164933
>Category:       bin
>Synopsis:       [nfs] [patch] mountd(8) drops mixed security flavors for multiple lines per same share
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 09 16:30:09 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Attila Bogár
>Release:        8.2-STABLE
>Organization:
Linguamatics
>Environment:
FreeBSD topaz.linguamatics.com 8.2-RELEASE-p6 FreeBSD 8.2-RELEASE-p6 #1: Wed Feb  8 14:21:11 GMT 2012     system@topaz.linguamatics.com:/usr/obj/usr/src/sys/LINGUAMATICS  amd64

>Description:
When multiple lines per share are present with different security flavors, the last line's security flavour is preserved for mountd(8) and the ones from previous linues are dropped from mountd.  However the exports are pushed correctly into the kernel line-by-line with the correct security flavor.

When trying to mount the nfs share from a client machine, mountd responds with a list of possible security flavors from the share's last line only.


>How-To-Repeat:
Compile a kernel:
- deselect NFSSERVER option
- select NFSD, KGSSAPI options
- add devices: crypto, cryptodev

Add to /etc/rc.conf:
  nfs_server_enable="YES"
  nfsv4_server_enable="NO"
  nfsuserd_enable="YES"
  nfsuserd_flags="16"
  mountd_enable="YES"
  rpc_lockd_enable="YES"
  rpc_statd_enable="YES"
  rpcbind_enable="YES"
  gssd_enable="YES"

Add nfs/fqdn@REALM keytab to /etc/krb5.keytab.
Set up /etc/krb5.conf

Create sample /etc/exports:
  /export/share -sec=sys host1.example.com
  /export/share -sec=krb5i host2.example.com

Try mounting /export/share from host1 using sec=sys. Mount will fail.

>Fix:
My proposed patch takes an union of the used security flavours per filesystem handle.  Although this is not the perfect solution as clients still can mount a share with a flavour they had not been exported to.  If doing such, they get permission denied from nfsd or error message saying the (nfs) server requires stronger authentication.

struct exportlist contains the security flavours per filesystem handle.

It would be more thorough if the security flavours were registered on a per host/network/default entry, similar to as they are pushed into the kernel with do_mount() function.


Patch attached with submission follows:

--- ./usr.sbin/mountd/mountd.c.orig	2011-04-20 22:00:24.000000000 +0100
+++ ./usr.sbin/mountd/mountd.c	2012-02-09 11:54:50.000000000 +0000
@@ -1170,6 +1170,7 @@
 	struct xucred anon;
 	char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
 	int len, has_host, exflags, got_nondir, dirplen, netgrp;
+	int xx_numsecflavors, xx_secflavors[MAXSECFLAVORS];
 
 	v4root_phase = 0;
 	dirhead = (struct dirlist *)NULL;
@@ -1191,6 +1192,7 @@
 		opt_flags = 0;
 		ep = (struct exportlist *)NULL;
 		dirp = NULL;
+		xx_numsecflavors = 0;
 
 		/*
 		 * Handle the V4 root dir.
@@ -1299,10 +1301,13 @@
 						  "making new ep fs=0x%x,0x%x",
 						  fsb.f_fsid.val[0],
 						  fsb.f_fsid.val[1]);
-					} else if (debug)
+					} else { if (debug)
 					    warnx("found ep fs=0x%x,0x%x",
 						fsb.f_fsid.val[0],
 						fsb.f_fsid.val[1]);
+					    xx_numsecflavors = ep->ex_numsecflavors;
+					    bcopy(ep->ex_secflavors, &xx_secflavors, sizeof(int)*xx_numsecflavors);
+					}
 				    }
 
 				    /*
@@ -1429,6 +1434,19 @@
 		}
 
 		/*
+		 * Merge security flavours
+		 */
+
+		int ci, cj;
+
+		for(ci=0;ci<xx_numsecflavors;ci++) {
+			for(cj = 0; cj<ep->ex_numsecflavors && xx_secflavors[ci]!=ep->ex_secflavors[cj];cj++);
+			if (cj==ep->ex_numsecflavors) {
+				ep->ex_secflavors[ep->ex_numsecflavors++] = xx_secflavors[ci];
+			}
+		}
+
+		/*
 		 * Success. Update the data structures.
 		 */
 		if (has_host) {


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202091622.q19GMY3h091558>