From owner-freebsd-fs@freebsd.org Sun May 15 13:42:51 2016 Return-Path: Delivered-To: freebsd-fs@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C0D37B3B7BC; Sun, 15 May 2016 13:42:51 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from citapm.icyb.net.ua (citapm.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id 73E7E1099; Sun, 15 May 2016 13:42:46 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from porto.starpoint.kiev.ua (porto-e.starpoint.kiev.ua [212.40.38.100]) by citapm.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id QAA04848; Sun, 15 May 2016 16:38:02 +0300 (EEST) (envelope-from avg@FreeBSD.org) Received: from localhost ([127.0.0.1]) by porto.starpoint.kiev.ua with esmtp (Exim 4.34 (FreeBSD)) id 1b1wF8-000GHJ-8t; Sun, 15 May 2016 16:38:02 +0300 To: freebsd-arch@FreeBSD.org, freebsd-fs From: Andriy Gapon Subject: mount / unmount and mountcheckdirs() Message-ID: <5c01bf62-b7b2-2e1d-bca5-859e6bf1f0e5@FreeBSD.org> Date: Sun, 15 May 2016 16:37:05 +0300 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:45.0) Gecko/20100101 Thunderbird/45.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 May 2016 13:42:51 -0000 I am curious about the purpose of mountcheckdirs() called when mounting and unmounting a filesystem. The function is described as such: /* * Scan all active processes and prisons to see if any of them have a current * or root directory of `olddp'. If so, replace them with the new mount point. */ and it seems to be used to "lift" processes and jails to a root of a new filesystem when it is mounted and to "lower" them onto a covered vnode (if any) when a filesystem is unmounted. What's the purpose of those actions? It's strange that the machinations are done at all, but it is stranger that they are applied only to processes and jails at exactly a covered vnode and a root vnode. Anything below in a filesystem's tree is left alone. Is there anything so very special about being at exactly those points? IMO, the machinations can have unexpected security consequences. A little bit of history. mountcheckdirs() was first added in r22521 (circa 1997) as checkdirs with a rather non-specific commit message. Initially it was used only when a filesystem was mounted. Then, in r73241 (circa 2002) the function was added to dounmount(): The checkdirs() function is called at mount time to find any process fd_cdir or fd_rdir pointers referencing the covered mountpoint vnode. It transfers these to point at the root of the new filesystem. However, this process was not reversed at unmount time, so processes with a cwd/root at a mount point would unexpectedly lose their cwd/root following a mount-unmount cycle at that mountpoint. ... Dounmount() now undoes the actions taken by checkdirs() at mount time; any process cdir/rdir pointers that reference the root vnode of the unmounted filesystem are transferred to the now-uncovered vnode. -- Andriy Gapon