bin/164933: [nfs] [patch] mountd(8) drops mixed security flavors for multiple lines per same share

Attila Bogár attila.bogar at
Thu Feb 9 16:30:10 UTC 2012

>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
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 09 16:30:09 UTC 2012
>Originator:     Attila Bogár
>Release:        8.2-STABLE
FreeBSD 8.2-RELEASE-p6 FreeBSD 8.2-RELEASE-p6 #1: Wed Feb  8 14:21:11 GMT 2012     system at  amd64

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.

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

Add to /etc/rc.conf:

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

Create sample /etc/exports:
  /export/share -sec=sys
  /export/share -sec=krb5i

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

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",
-					} else if (debug)
+					} else { if (debug)
 					    warnx("found ep fs=0x%x,0x%x",
+					    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) {


More information about the freebsd-bugs mailing list