Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 7 Apr 2011 20:47:49 GMT
From:      Marcin Wisnicki <mwisnicki+freebsd@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/156258: find(1) does not detect nullfs
Message-ID:  <201104072047.p37Klnwx053408@red.freebsd.org>
Resent-Message-ID: <201104072050.p37KoBZR077998@freefall.freebsd.org>

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

>Number:         156258
>Category:       bin
>Synopsis:       find(1) does not detect nullfs
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 07 20:50:11 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Marcin Wisnicki
>Release:        8.2-STABLE
>Organization:
>Environment:
>Description:
find(1) utility does not correctly detect nullfs filesystems with -fstype option.

Nullfs copies statfs.f_type from lower fs, f_fstypename however is set to nullfs.
>How-To-Repeat:
% mkdir /jails
% mount -t nullfs /tmp /jails

% find /jails -maxdepth 0 -fstype nullfs
% gfind /jails -maxdepth 0 -fstype nullfs
/jails
>Fix:
Compare fstypename. This is how gnu find and find on other *BSDs work.
Patch adopted from NetBSD (from 1994 ;) is below.

Also I have added XXX comment to val_flags assignment, this is not related to the fix but it did catch my attention.
I don't understand why gcc emits no warning when assigning uint64 field to int variable. I've tried WARNS=6 -Wall -pedantic -Wconversion but it didn't help. Can someone explain this to me ?

Patch attached with submission follows:

diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index 26c022c..cc75aaf 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -846,7 +846,8 @@ f_fstype(PLAN *plan, FTSENT *entry)
 	static dev_t curdev;	/* need a guaranteed illegal dev value */
 	static int first = 1;
 	struct statfs sb;
-	static int val_type, val_flags;
+	static int val_flags;
+	static char fstype[sizeof(sb.f_fstypename)];
 	char *p, save[2] = {0,0};
 
 	if ((plan->flags & F_MTMASK) == F_MTUNKNOWN)
@@ -887,14 +888,15 @@ f_fstype(PLAN *plan, FTSENT *entry)
 		 * Further tests may need both of these values, so
 		 * always copy both of them.
 		 */
+		/* XXX integer truncation ? */
 		val_flags = sb.f_flags;
-		val_type = sb.f_type;
+		strlcpy(fstype, sb.f_fstypename, sizeof(fstype));
 	}
 	switch (plan->flags & F_MTMASK) {
 	case F_MTFLAG:
 		return val_flags & plan->mt_data;
 	case F_MTTYPE:
-		return val_type == plan->mt_data;
+		return (strncmp(fstype, plan->c_data, sizeof(fstype)) == 0);
 	default:
 		abort();
 	}
@@ -905,22 +907,12 @@ c_fstype(OPTION *option, char ***argvp)
 {
 	char *fsname;
 	PLAN *new;
-	struct xvfsconf vfc;
 
 	fsname = nextarg(option, argvp);
 	ftsoptions &= ~FTS_NOSTAT;
 
 	new = palloc(option);
 
-	/*
-	 * Check first for a filesystem name.
-	 */
-	if (getvfsbyname(fsname, &vfc) == 0) {
-		new->flags |= F_MTTYPE;
-		new->mt_data = vfc.vfc_typenum;
-		return new;
-	}
-
 	switch (*fsname) {
 	case 'l':
 		if (!strcmp(fsname, "local")) {
@@ -938,12 +930,8 @@ c_fstype(OPTION *option, char ***argvp)
 		break;
 	}
 
-	/*
-	 * We need to make filesystem checks for filesystems
-	 * that exists but aren't in the kernel work.
-	 */
-	fprintf(stderr, "Warning: Unknown filesystem type %s\n", fsname);
-	new->flags |= F_MTUNKNOWN;
+	new->flags |= F_MTTYPE;
+	new->c_data = fsname;
 	return new;
 }
 


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



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