From nobody@FreeBSD.org  Mon Nov 22 14:56:04 2004
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 5909716A4CE
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Nov 2004 14:56:04 +0000 (GMT)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 238DD43D54
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Nov 2004 14:56:04 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id iAMEu3Ko037229
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Nov 2004 14:56:03 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id iAMEu3Qo037228;
	Mon, 22 Nov 2004 14:56:03 GMT
	(envelope-from nobody)
Message-Id: <200411221456.iAMEu3Qo037228@www.freebsd.org>
Date: Mon, 22 Nov 2004 14:56:03 GMT
From: Derek Tattersall <dlt@mebtel.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Write to fifo with no reader fails in 6.0 current
X-Send-Pr-Version: www-2.3

>Number:         74242
>Category:       kern
>Synopsis:       Write to fifo with no reader fails in 6.0 current
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    rwatson
>State:          suspended
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 22 15:00:54 GMT 2004
>Closed-Date:    
>Last-Modified:  Sun Jun 22 22:00:07 UTC 2008
>Originator:     Derek Tattersall
>Release:        6.0 -  21 November 2004
>Organization:
>Environment:
FreeBSD lorne.arm.org 6.0-CURRENT FreeBSD 6.0-CURRENT #1: Sun Nov 21 12:00:32 EST 2004     root@lorne.arm.org:/usr/obj/usr/src/sys/LORNE  i386     
>Description:
  Problem: Writing to a fifo before a reader is present results in the
write returning -1 with errno 45 "operation not supported".  This
behavior is new with a system cvsup'ed yesterday.

($?=0)dlt@lorne 1021 dlt% uname -a
FreeBSD lorne.arm.org 6.0-CURRENT FreeBSD 6.0-CURRENT #1: Sun Nov 21
12:00:32 EST 2004     root@lorne.arm.org:/usr/obj/usr/src/sys/LORNE
i386

The following two programs, speak.c (writer) and tick.c (reader)
demonstrate the problem.  If speak is started before tick, the write
always fails.  If tick is started before speak, everything works as
expected.  This code is slightly modified from code on Beej's Unix IPC
site.

speak.c --------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define FIFO_NAME "american_maid"

main()
{
  char s[300];
  int num, fd;

  /* don't forget to error check this stuff!! */
  /*mknod(FIFO_NAME, S_IFIFO | 0666, 0);*/
  mkfifo(FIFO_NAME, 0666);

  printf("waiting for readers...\n");
  fd = open(FIFO_NAME, O_WRONLY);
  printf("got a reader--type some stuff\n");

  while (gets(s), !feof(stdin)) {
    if ((num = write(fd, s, strlen(s))) == -1)
      perror("write");
    else
      printf("speak: wrote %d bytes\n", num);
  }
}
speak.c-------------------------------------------------------------
tick.c -------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define FIFO_NAME "american_maid"

main()
{
  char s[300];
  int num, fd;

  /* don't forget to error check this stuff!! */
  mknod(FIFO_NAME, S_IFIFO | 0666, 0);

  printf("waiting for writers...\n");
  fd = open(FIFO_NAME, O_RDONLY);
  printf("got a writer:\n");

  do {
    if ((num = read(fd, s, 300)) == -1)
      perror("read");
    else {
      s[num] = '\0';
      printf("tick: read %d bytes: \"%s\"\n", num, s);
    }
  } while (num > 0);
}
tick.c-------------------------------------------------------------

Note:  On a 5.3 RELEASE system it does not matter which program is
started first.  In fact, this code has worked on current up through
11/10/2004.
    
>How-To-Repeat:
 Using speak, compiled with "cc -o speak speak.c" and tick compiled with "cc -o tick tick.c", start speak in an xterm or console, then start tick in another xterm or console.  Type in the speak window, mash newline, observe error message in speak window or console.  Note that starting tick first then speak, and typing in the speak window shows no error.
>Fix:
      
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->phk 
Responsible-Changed-By: rwatson 
Responsible-Changed-When: Mon Nov 22 21:55:41 GMT 2004 
Responsible-Changed-Why:  
Change ownership to Poul-Henning Kamp, who has recently had his hands in 
the fifo code. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=74242 
Responsible-Changed-From-To: phk->rwatson 
Responsible-Changed-By: rwatson 
Responsible-Changed-When: Tue Sep 13 10:49:02 GMT 2005 
Responsible-Changed-Why:  
Grab ownership of this PR since I've been fixing a number of bugs in the 
fifofs code. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=74242 
State-Changed-From-To: open->feedback 
State-Changed-By: rwatson 
State-Changed-When: Tue Sep 13 11:10:48 GMT 2005 
State-Changed-Why:  
When I run the "tick" and "speak" programs as described, I get EBADF back 
from the read() call in "tick", as open() has failed, which results from 
mknod() failing with EPERM.  This somewhat obscure failure mode was due 
to a lack of error checking in the test programs, which didn't confirm 
that the fifo had been created or opened before attempting I/O on the 
returned descriptor.  If run sequentially, "tick" actually does work, 
since "speak" calls mkfifo(), which succeeds.  When the mknod() call in 
"tick" is replaced with mkfifo(), the tests appear to operate correctly 
on recent 7.x.  When I ran the test programs as provided on 4.x, they 
failed, but worked with the mkfifo change. 

There appears to be some disagreement about whether mknod(S_FIFO) should 
work for unprivileged users.  FreeBSD 4.x does not permit this.  FreeBSD 
6.x and 7.x do not permit this.  It could well be that FreeBSD 5.x does 
permit this.  POSIX indicates that privilege is required for non-S_FIFO, 
but appears to allow mknod(2) as an acceptable interface to create fifos 
as an unprivileged user.  It could be that we should broaden the scope 
of mknod(2) to require privilege only for non-fifo objects, in order to 
provide more portable support for fifos. 

Could you confirm that, in your environment, the source of the read() 
error is in fact that mknod() has failed (detected by checking for a 
return value of -1, and then printed using err(-1, "mknod")), and that 
if the fifo is created using mkfifo(), "tick" operates properly in your 
environment?  This would help us identify that there isn't another bug 
lurking here. 

FYI, it could be that FreeBSD 5.3 appeared to allow this by virtue of 
the fact that the order in which the provided programs are run is quite 
significant in how they operate: later runs of "tick" will work fine as 
the fifo has been created by a prior run of "speak", and then not been 
removed. 

Thanks, 

Robert Watson 


http://www.freebsd.org/cgi/query-pr.cgi?pr=74242 
State-Changed-From-To: feedback->suspended 
State-Changed-By: rwatson 
State-Changed-When: Thu Sep 15 20:21:32 GMT 2005 
State-Changed-Why:  
Place this PR into a suspended state.  We have established that the 
specific symptoms were the result of a software bug, but there is an 
open issue relating to whether we need to modify our mknod() system 
call to allow the unprivileged creation of fifos in order to conform 
to more recent POSIX revisions.  After some cogitation on the issue, 
we may want to re-open this PR as a feature request. 


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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/74242: commit references a PR
Date: Sun, 22 Jun 2008 21:51:49 +0000 (UTC)

 rwatson     2008-06-22 21:51:32 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/kern             vfs_syscalls.c 
   Log:
   SVN rev 179936 on 2008-06-22 21:51:32Z by rwatson
   
   If S_IFIFO is passed to mknod(2), invoke kern_mkfifoat(9) to create a
   FIFO, as required by SUSv3.  No specific privilege check is performed
   in this case, as FIFOs may be created by unprivileged processes
   (subject to the normal file system name space restrictions that may be
   in place).
   
   Unlike the Apple implementation, we reject requests to create a FIFO
   using mknod(2) if there is a non-zero dev argument to the system call,
   which is permitted by the Open Group specification ("... undefined
   ...").  We might want to revise this if we find it causes
   compatibility problems for applications in practice.
   
   PR:             kern/74242, kern/68459
   Obtained from:  Apple, Inc.
   MFC after:      3 weeks
   
   Revision  Changes    Path
   1.454     +4 -0      src/sys/kern/vfs_syscalls.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
>Unformatted:
