standards/154873: ZFS violates POSIX on open/O_CREAT -> ftruncate
Mark Martinec
Mark.Martinec at ijs.si
Sat Feb 19 03:10:12 UTC 2011
>Number: 154873
>Category: standards
>Synopsis: ZFS violates POSIX on open/O_CREAT -> ftruncate
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-standards
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Feb 19 03:10:11 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator: Mark Martinec
>Release: FreeBSD 8.1-RELEASE-p2 amd64
>Organization:
Jozef Stefan Institute
>Environment:
FreeBSD neli.ijs.si 8.1-RELEASE-p2 FreeBSD 8.1-RELEASE-p2 #12: Thu Dec 2 14:30:03 CET 2010 mark at neli.ijs.si:/usr/obj/usr/src/sys/NELI amd64
>Description:
POSIX.1-2008 requires that the third argument to open(2) on
O_CREAT does not affect whether the file is open for reading,
writing, or for both. A subsequent ftruncate should not
depend on access permission bits of the file, but solely
on the read/write flags specified on the open(2).
The bug affects a mailer Postfix, which reports a
permission problem on ftruncate, affecting the smtpd
service when option speed_adjust is requested.
As the problem is in the file system violating a POSIX
specification and not in the application, it is unlikely
that the program will be modified.
Reproducible on:
FreeBSD 8.1-RELEASE-p2, ZFS: pool version 14, ZFS version 3
as well as on:
FreeBSD 8.2-RC3, ZFS: pool version 15, ZFS version 4
>How-To-Repeat:
Run the following test program. It will report:
Error truncating: Permission denied
when (cwd) on a ZFS file system, but will pass clean
when on UFS or on some other file system.
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
const char fname[] = "truncate-posix-test.tmp";
/* POSIX.1-2008: ( http://www.opengroup.org/onlinepubs/9699919799/ )
* open() [...] O_CREAT [...] The file status flags and file
* access modes of the open file description shall be set according
* to the value of oflag. [...] The argument following the oflag
* argument does not affect whether the file is open for reading,
* writing, or for both.
*
* In other words, read/write access is controlled with the
* O_RDWR flags, not the read/write permissions argument.
*
* Create a file with mode 0, i.e. all access permission bits off:
*/
int fd = open(fname, O_CREAT|O_RDWR|O_EXCL, 0);
if (fd < 0) { perror("Error creating file"); return 1; }
if (unlink(fname) < 0) perror("Error unlinking");
/* ftruncate should succeed,
* it must not depend on access permission bits, its rights
* should solely be governed by an O_RDWR file access flag.
*
* This FAILS on a ZFS file system, reporting "Permission denied"!
*/
if (ftruncate(fd,0) < 0) perror("Error truncating");
if (close(fd) < 0) perror("Error closing");
return 0;
}
>Fix:
Fix unknown.
Work around by not using ZFS, or by allowing less strict
access permission bits on open(2) - which may be hard to achieve
if code is buried inside some application.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-standards
mailing list