Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Feb 2013 09:05:15 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Rick Macklem <rmacklem@uoguelph.ca>
Cc:        FreeBSD Filesystems <freebsd-fs@freebsd.org>, Sergey Kandaurov <pluknet@freebsd.org>
Subject:   Re: should vn_fullpath1() ever return a path with "." in it?
Message-ID:  <20130228070515.GK2454@kib.kiev.ua>
In-Reply-To: <707174204.3391839.1362020362019.JavaMail.root@erie.cs.uoguelph.ca>
References:  <860349954.3391816.1362020304865.JavaMail.root@erie.cs.uoguelph.ca> <707174204.3391839.1362020362019.JavaMail.root@erie.cs.uoguelph.ca>

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

--TOcCsfss/f1fJPnO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Feb 27, 2013 at 09:59:22PM -0500, Rick Macklem wrote:
> Hi,
>=20
> Sergey Kandaurov reported a problem where getcwd() returns a
> path with "/./" imbedded in it for an NFSv4 mount. This is
> caused by a mount point crossing on the server when at the
> server's root because vn_fullpath1() uses VV_ROOT to spot
> mount point crossings.
>=20
> The current workaround is to use the sysctls:
> debug.disablegetcwd=3D1
> debug.disablefullpath=3D1
>=20
> However, it would be nice to fix this when vn_fullpath1()
> is being used.
>=20
> A simple fix is to have vn_fullpath1() fail when it finds
> "." as a directory match in the path. When vn_fullpath1()
> fails, the syscalls fail and that allows the libc algorithm
> to be used (which works for this case because it doesn't
> depend on VV_ROOT being set, etc).
>=20
> So, I am wondering if a patch (I have attached one) that
> makes vn_fullpath1() fail when it matches "." will break
> anything else? (I don't think so, since the code checks
> for VV_ROOT in the loop above the check for a match of
> ".", but I am not sure?)
>=20
> Thanks for any input w.r.t. this, rick

> --- kern/vfs_cache.c.sav	2013-02-27 20:44:42.000000000 -0500
> +++ kern/vfs_cache.c	2013-02-27 21:10:39.000000000 -0500
> @@ -1333,6 +1333,20 @@ vn_fullpath1(struct thread *td, struct v
>  			    startvp, NULL, 0, 0);
>  			break;
>  		}
> +		if (buf[buflen] =3D=3D '.' && (buf[buflen + 1] =3D=3D '\0' ||
> +		    buf[buflen + 1] =3D=3D '/')) {
> +			/*
> +			 * Fail if it matched ".". This should only happen
> +			 * for NFSv4 mounts that cross server mount points.
> +			 */
> +			CACHE_RUNLOCK();
> +			vrele(vp);
> +			numfullpathfail1++;
> +			error =3D ENOENT;
> +			SDT_PROBE(vfs, namecache, fullpath, return,
> +			    error, vp, NULL, 0, 0);
> +			break;
> +		}
>  		buf[--buflen] =3D '/';
>  		slash_prefixed =3D 1;
>  	}

I do not quite understand this. Did the dvp (parent) vnode returned by
VOP_VPTOCNP() equal to vp (child) vnode in the case of the "." name ?
It must be, for the correct operation, but also it should cause the almost
infinite loop in the vn_fullpath1(). The loop is not really infinite due
to a limited size of the buffer where the infinite amount of "./" is placed.

Anyway, I think we should do better than this patch, even if it is
legitimate. I think that the better place to check the condition is the
default implementation of VOP_VPTOCNP(). Am I right that this is where
it broke for you ?

diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 00d064e..1dd0185 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -856,8 +856,12 @@ vop_stdvptocnp(struct vop_vptocnp_args *ap)
 				error =3D ENOMEM;
 				goto out;
 			}
-			bcopy(dp->d_name, buf + i, dp->d_namlen);
-			error =3D 0;
+			if (dp->d_namlen =3D=3D 1 && dp->d_name[0] =3D=3D '.') {
+				error =3D ENOENT;
+			} else {
+				bcopy(dp->d_name, buf + i, dp->d_namlen);
+				error =3D 0;
+			}
 			goto out;
 		}
 	} while (len > 0 || !eofflag);

--TOcCsfss/f1fJPnO
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)

iQIcBAEBAgAGBQJRLwGqAAoJEJDCuSvBvK1BDWAP/2btss4VP6rNctXFRP+Sg89v
HyhDquJdAUqhSCbQgRMTUrUQWf/K/O3RJAZ+/6S062JQH7vYfvGkB7YFnMVk0oml
2Lho0Qie4lMM2zwH/otWpJ3L0FxRed5dG3vB0jmBYXFTizzGiFPx0jgr2X40vuVE
n6cdICidbApt4hbuSSBE3V2c1XqpufbOWYp3uKrqdQ/twMdR6nsEOGnMeGCNaqm3
tDv2LNLJIz+6MYwerCeELkNuxQpPZRMCHL54t72WeIbhGcC5aK225txpyw7sJPhG
UDqLDGEuwSj5xbwqt9ISEkd2HqumzhRuUhmTX/popF+TDaJP6uQAEVwwS4UxdMCt
y+qzn+zO4xlFljHwGGaxf+8abrfZ/31+w3riSOd3HI3MPVbEkHH9Z05LX7bjabeO
Xs0L3Yeh1LDL6/adwkpZYdUHcWwNhywzXt0oduVXO9NAhPvlxDRs2o9yjkvJCzob
axjcwY6H8QEnHLwlTsGO/lWYQLtSzXr4EmQta2EjjmMMby7J7dg6NdS+d1DfViZc
eZCXx8sl3LyPRYXUwZ72522csR974TVirHFWh0dqsUkcVLxLQdQE8Pdkx2UWlyJA
KaWmSsf8b6YN3bVmQbQwSsrM97r7o/W06OgscZXwxqZUPNy5WlRl+VfxrjPGspnd
JrIyI8FEx0oKz63uan5Z
=d3e2
-----END PGP SIGNATURE-----

--TOcCsfss/f1fJPnO--



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