From owner-freebsd-fs@FreeBSD.ORG Tue Feb 21 02:38:04 2012 Return-Path: Delivered-To: freebsd-fs@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 94B86106566B for ; Tue, 21 Feb 2012 02:38:04 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from fallbackmx09.syd.optusnet.com.au (fallbackmx09.syd.optusnet.com.au [211.29.132.242]) by mx1.freebsd.org (Postfix) with ESMTP id 2C9AB8FC14 for ; Tue, 21 Feb 2012 02:38:03 +0000 (UTC) Received: from mail08.syd.optusnet.com.au (mail08.syd.optusnet.com.au [211.29.132.189]) by fallbackmx09.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id q1L2RvJx031027 for ; Tue, 21 Feb 2012 13:27:57 +1100 Received: from c211-30-171-136.carlnfd1.nsw.optusnet.com.au (c211-30-171-136.carlnfd1.nsw.optusnet.com.au [211.30.171.136]) by mail08.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id q1L2Rrn7006192 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 21 Feb 2012 13:27:54 +1100 Date: Tue, 21 Feb 2012 13:27:53 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Mattias Lindgren In-Reply-To: <201202201920.q1KJKFXE058032@freefall.freebsd.org> Message-ID: <20120221111121.I2928@besplex.bde.org> References: <201202201920.q1KJKFXE058032@freefall.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-fs@FreeBSD.org Subject: Re: kern/149495: [zfs] chflags sappend on zfs not working right X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Feb 2012 02:38:04 -0000 On Mon, 20 Feb 2012, Mattias Lindgren wrote: > Having similar issues in FreeBSD 9-AMD64 with ZFS v 28 > > $ mkdir critical > $ touch critical/critical.log > $ sudo chmod o= critical > > $ sudo chflags sappnd critical > $ sudo chflags sappnd critical/* > > $ echo "test" > critical/critical.log > -bash: critical/critical.log: Operation not permitted > $ echo "test" >> critical/critical.log > $ grep test critical/critical.log > test > $ rm -rf critical/critical.log > $ ls -l critical/ > total 0 > > Am under the impression that I should not be able to delete files once the > sappend flag has been set. It is a bug in 4.4BSD and ffs that [su]append prevents deleting files. Deletion of files should be prevented only by the [su]nounlink flag and the [su]immutable flag, but 4.4BSD didn't have the [su]nounlink flag, and it is insecure to allow unlinking any [su]append file, so 4.4BSD and ffs have the non-orthogonal behaviour of never allowing one to be unlinked, and this wasn't changed when [su]nounlink was added. This bug apparently isn't implemented in zfs. I don't know much about zfs, but zfs_zacces_delete() seems to only test the immutable and nounlink flags. Try adding the append flag there. Nearby bugs: - the [su]append flags have the silly abbreviations [su]appnd in chflags(1). ls -o output to show these flags will be wide anyway, and 1 character is not worth saving. The 1-char difference is just confusing for input. - the [su]nounlink flags have the much worse abbreviations [su]unlnk in chflags(1). Even the non-abbreviated forms [su]unlink are missing their 'no' prefix. So unlink means nounlink, and if you want to unset this, you use no[su]unlink which actually means nonounlink, that is, unlink, that is, unlinking is not restricted by the flag. The u prefix also makes uunlink hard to read. unounlink would be better. The following is hopefully only in ffs (except in my version): - setting of flags is non-orthogonal. Normal read-modify-write operations don't work for users, although they work for root. The details of this bug were changed between 4.4BSD-Lite1 and 4.4BSD-Lite2 and reached FreeBSD in chflags(2)'s code in 1997 and in chflags(2)'s man page in 2006 (the latter with grammar errors). This makes chflags(2) very difficult to use. Naive programs like chflags(1) don't understand this, and just do a simple read-modify-write operation. This gives weird behaviour which can be worked around if you understand chflags(2) better than chflags(1) does. For example: Suppose you have a file with some harmless system flag like `archive' (this is the only one). This doesn't prevent anyone changing their flags. But it prevents users changing their flags in the normal way. "chflags uchg file" will fail because it is turned into a chflags(2) request to set the existing archive flag as well as the uchg flag. As documented, the former is not permitted. So to set your uchg flag while preserving the archive flag (which you can't change either way), you must ask for the archive flag to be cleared: "chflags noarch uchg" after first determining which system flags are set. Similarly for using chflags(2), except now you must clear all the system flags that are set, and can do this more easily by setting all the system flags. Clearing all your flags is easier: just ask for flags of 0 with chflags(either 1 or 2). However, if you are root, then you must not request any system flags to be cleared unless you actually want them cleared, since the request will actually work for root. However2, since ffs has null support for the archive flag, setting it for ffs is almost useless and rarely done, so the bug has little affect. My version also allows user changes if only the sunlink flag is set (why should preventing unlinking prevent chmod() when it doesn't prevent truncating the file or filling it with garbage?). But I now thing that this is not a good idea and the change should go the other way, so that uunlink prevents changes like sunlink does. Bruce