Bug 154873 - ZFS violates POSIX on open/O_CREAT -> ftruncate
Summary: ZFS violates POSIX on open/O_CREAT -> ftruncate
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: 8.1-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: Pawel Jakub Dawidek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-19 03:10 UTC by Mark.Martinec
Modified: 2016-08-08 07:50 UTC (History)
0 users

See Also:
bugmeister: mfc-stable10?
bugmeister: mfc-stable9?
bugmeister: mfc-stable8?


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark.Martinec 2011-02-19 03:10:11 UTC
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

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.
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;
}
Comment 1 Mark.Martinec 2011-02-24 16:38:27 UTC
> Mark Martinec wrote at 03:06 +0000 on Feb 19, 2011:
>  >   Error truncating: Permission denied
>  > when (cwd) on a ZFS file system, but will pass clean
>  > when on UFS or on some other file system.
> 
> The test gets 'Error truncating: Permission denied' on nfs also
> (tested with freebsd implementation of v3).
 
> Have you checked with the fs@ mailing list?

I sent a copy of this PR to the freebsd-fs@freebsd.org mailing list,
with no response so far ...

  Mark
Comment 2 Pawel Jakub Dawidek freebsd_committer freebsd_triage 2011-03-05 17:29:48 UTC
Responsible Changed
From-To: freebsd-standards->pjd

I'll take this one. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=154873 

Date: Wed,  9 Mar 2011 23:11:43 +0000 (UTC)
Comment 3 Pawel Jakub Dawidek freebsd_committer freebsd_triage 2011-03-24 20:28:17 UTC
State Changed
From-To: open->patched

Fix committed to HEAD. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=154873 

Date: Thu, 24 Mar 2011 20:28:24 +0000 (UTC)
Comment 4 Mark Linimon freebsd_committer freebsd_triage 2016-08-08 07:50:23 UTC
Fixed back in 2011.