kern/161481: mount fails with ENAMETOOLONG with path shorter than 255 // 1023 characters

Bruce Evans brde at optusnet.com.au
Tue Oct 11 10:50:04 UTC 2011


The following reply was made to PR kern/161481; it has been noted by GNATS.

From: Bruce Evans <brde at optusnet.com.au>
To: Garrett Cooper <yanegomi at gmail.com>
Cc: freebsd-gnats-submit at freebsd.org, freebsd-bugs at freebsd.org
Subject: Re: kern/161481: mount fails with ENAMETOOLONG with path shorter
 than 255 // 1023 characters
Date: Tue, 11 Oct 2011 21:44:05 +1100 (EST)

 On Tue, 11 Oct 2011, Garrett Cooper wrote:
 
 >> Description:
 > mount(2) claims that it should fail with ENAMETOOLONG if the path is <= 255 or 1023 characters:
 >
 >     [ENAMETOOLONG]     A component of a pathname exceeded 255 characters, or
 >                        the entire length of a path name exceeded 1023 charac-
 >                        ters.
 >
 > In practice, that isn't true:
 >
 > # mount -t nullfs -o noatime /nfs/scratch/freenas-2/freenas/projects/freenas8-plugins/obj.amd64/ports/distfiles /nfs/scratch/freenas-2/freenas/projects/freenas8-plugins/obj.amd64/_.w/usr/ports/distfiles
 > mount_nullfs: File name too long
 
 There are limit of MNAMELEN = 88 and OMNAMELEN (a bit smaller) for mount().
 
 This seems to be a new bug.  In FreeBSD[1-4], mount() used normal pathname
 stuff and there were no references to MNAMELEN in vfs, and file systems
 like ffs silently ignored the ENAMETOOLONG error for copyinstr() of
 the user pathname to mp->mnt_stat.f_mntonname[] (which has size MNAMELEN).
 (This copyinstr() isn't quite normal pathname stuff either.  copyinstr()
 to the namei buffer and using that for everything in the kernel would be
 normal.  ffs_mount() also handles namei initialization and I think it
 uses a separate copyinstr() for f_mntonname[] in at least some cases
 because namei initialization occurs later.)
 
 This seems to have been broken somewhere in FreeBSD-5, probably
 collaterally with nmount().  FreeBSD-5.2 has up-front checks that the
 pathname fits in a buffer of size MNAMELEN, in both nmount(9) and mount(9).
 For nmount(), the pathname is far from normal, since it is passed as
 an option string.  For mount(), the pathname starts as normal, but it is
 copyinstr()'ed into a malloc buffer of size MNAMELEN to join up with
 nmount().  ffs no longer (still in 5.2) copyinstr()'s the user path to
 mp->mnt_stat.f_mntonname[], but it still does an NDINIT() on args.fspec
 with arg UIO_USERSPACE; that now seems to work only accidentally, since
 the path is actually in UIO_SYSSPACE.  Now in -current, even more of the
 initialization has been moved up to vfs;  ffs still does the NDINIT() but
 it uses arg UIO_SYSSPACE.
 
 ISTR old PRs about almost the opposite problem, that you could mount things
 with paths so long that you couldn't easily unmount them, because the
 pathname in mp->mnt_stat.f_mntonname[] is truncated.
 
 Bruce


More information about the freebsd-bugs mailing list