From owner-freebsd-bugs@FreeBSD.ORG Wed Feb 18 02:07:57 2015 Return-Path: Delivered-To: freebsd-bugs@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2E10FC93 for ; Wed, 18 Feb 2015 02:07:57 +0000 (UTC) Received: from kenobi.freebsd.org (kenobi.freebsd.org [IPv6:2001:1900:2254:206a::16:76]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 13F5D916 for ; Wed, 18 Feb 2015 02:07:57 +0000 (UTC) Received: from bugs.freebsd.org ([127.0.1.118]) by kenobi.freebsd.org (8.14.9/8.14.9) with ESMTP id t1I27uwr079857 for ; Wed, 18 Feb 2015 02:07:56 GMT (envelope-from bugzilla-noreply@freebsd.org) From: bugzilla-noreply@freebsd.org To: freebsd-bugs@FreeBSD.org Subject: [Bug 197778] Implement the AT_EMPTY_PATH race free Linux extension Date: Wed, 18 Feb 2015 02:07:57 +0000 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: Base System X-Bugzilla-Component: kern X-Bugzilla-Version: 11.0-CURRENT X-Bugzilla-Keywords: X-Bugzilla-Severity: Affects Many People X-Bugzilla-Who: s_bugzilla@nedprod.com X-Bugzilla-Status: New X-Bugzilla-Priority: --- X-Bugzilla-Assigned-To: freebsd-bugs@FreeBSD.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version rep_platform op_sys bug_status bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: https://bugs.freebsd.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Feb 2015 02:07:57 -0000 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197778 Bug ID: 197778 Summary: Implement the AT_EMPTY_PATH race free Linux extension Product: Base System Version: 11.0-CURRENT Hardware: Any OS: Any Status: New Severity: Affects Many People Priority: --- Component: kern Assignee: freebsd-bugs@FreeBSD.org Reporter: s_bugzilla@nedprod.com Related: #197695 Due to only accepting paths, POSIX makes it hard to unlink and rename files without creating race conditions. For example to unlink a file as safely as is possible under POSIX: 1. Get one of the current paths of the open file descriptor using any facility provided if #197695 were implement. 2. Open its containing directory. 3. Do a fstatat() on the containing directory for the leafname of the open file descriptor, checking if the device ids and inodes match the ones for our file descriptor. 4. If they match, do an unlinkat() to remove the leafname. NOTE THIS IS RACY as another program could swap our leafname for another between the fstatat and the unlinkat. This raciness is disagreeable in this modern day and age. Moreover, Linux has partially added an extension via the AT_EMPTY_PATH flag which enables the XXXat() suite of functions work directly with the file descriptor. At the time of writing (Feb 2015), Linux implements the AT_EMPTY_PATH extension for: linkat(), fchownat(), fstatat(), name_to_handle_at(). The AT_EMPTY_PATH extension works as follows, so to create a new hard link for some file descriptor: linkat(fd, "", dirh, "name", AT_EMPTY_PATH) Note the empty path, and the passing in of a file descriptor which may or may not refer to a directory as the olddirh fd normally must. There are some obviously useful missing functions which could do with the AT_EMPTY_PATH extension: unlinkat(), renameat(). I have filed a feature request for those with the Linux kernel at https://bugzilla.kernel.org/show_bug.cgi?id=93441. Note that because Linux allows the direct opening of symlinks via the flag O_PATH, on Linux you can use linkat() to duplicate a symlink race free. As FreeBSD doesn't provide the ability to directly open symlinks, I'd actually make the total list of functions which this request asks for the AT_EMPTY_PATH extension upon to be: linkat(), fchownat(), fstatat(), unlinkat(), renameat(), symlinkat(), faccessat(), fchmodat(). Of these, renameat() and symlinkat() currently do not take a flags parameter. You could varargs those, or else enable the above functions to treat a null path fragment as equivalent to the dirh being the source filing system entry being modified i.e. a null path fragment = AT_EMPTY_PATH semantics. Or indeed additional f* variants of the non-at functions could be added which consume file descriptors instead of paths e.g. the oft wished for flink() (more discussion is at http://lwn.net/Articles/562488/). The point here is making it possible to use the filing system without any possibility of race conditions, something only Microsoft Windows currently permits. Some may observe that all this is a potential security hole e.g. child processes supposedly sandboxed could unlink or cause mischief with file descriptors they inherit, or otherwise destroy data. A similar argument could be fielded against #197695, except that every major OS except for FreeBSD has provided fd to path reading for years and I am unaware of any security issues which have emerged. For obvious reasons any of the above functions should fail if their path based equivalent would fail from the privileges available to a child process. Niall -- You are receiving this mail because: You are the assignee for the bug.