Subject: lib/7206: patch to intro(2) and revoke(2) to better explain possible EBADF causes
To: None <gnats-bugs@gnats.netbsd.org>
From: None <woods@mail.weird.com>
List: netbsd-bugs
Date: 03/22/1999 02:01:19
>Number:         7206
>Category:       lib
>Synopsis:       patch to intro(2) and revoke(2) to better explain possible EBADF causes
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          doc-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 21 23:05:00 1999
>Last-Modified:
>Originator:     Greg A. Woods
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Release:        NetBSD-current Sun Mar 21 07:37:32 EST 1999
>Environment:

>Description:

	There are many places where EBADF is used to describe a system
	call that's failed because the file descriptor is "invalid".

	However only in revoke(2) is it mentioned that this call can be
	one of the reasons for a file descriptor being "invalid".

	It would also appear that at some time prior to 1.3I NetBSD's
	revoke(2) system call was "fixed" so that it would work with any
	file, not just character and block device files.

>How-To-Repeat:

	Encounter an EBADF from fstat() and it would fail on a file
	opened with O_RDWR when close() would succeed:

01:53 [622] $ cat tfstat.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

int
main(argc, argv)
        int     argc;
        char    *argv[];
{
        struct stat sb;

        if (revoke("revoked") < 0)
                err(1, "revoke(revoked)");
        if (fstat(0, &sb) < 0)
                err(1, "stdin");
        exit(0);
}
01:54 [623] $ touch revoked  
01:54 [623] $ ./tfstat < revoked  
stdin: Bad file descriptor
ksh: exit code: 1

	The problem was first encountered with Postfix failing to accept
	e-mail from FreeBSD's cron which doesn't [yet] use daemon(3) and
	doesn't close file descriptors that were open on /dev/console.
	The diagnosis was done by Peter Wemm <peter@netplex.com.au>.

	Further experimentation by myself revealed that NetBSD as of
	1.3I or before now seems to allow any file to be revoke()d.

>Fix:

	check that revoke(2) really is universal to all files now and
	then apply the following patches

	any system call returning EBADF because of revoke(2) should
	probably .Xr it too -- not everyone remembers to read intro(2),
	not even me!  ;-)

Index: src/lib/libc/sys/intro.2
===================================================================
RCS file: /cvs/NetBSD/src/lib/libc/sys/intro.2,v
retrieving revision 1.1.1.2
diff -c -c -r1.1.1.2 src/lib/libc/sys/intro.2
*** src/lib/libc/sys/intro.2	1998/05/03 21:14:10	1.1.1.2
--- src/lib/libc/sys/intro.2	1999/03/22 06:42:56
***************
*** 33,39 ****
  .\"
  .\"     @(#)intro.2	8.5 (Berkeley) 2/27/95
  .\"
! .Dd February 8, 1998
  .Dt INTRO 2
  .Os BSD 4
  .Sh NAME
--- 33,39 ----
  .\"
  .\"     @(#)intro.2	8.5 (Berkeley) 2/27/95
  .\"
! .Dd March 22, 1999
  .Dt INTRO 2
  .Os BSD 4
  .Sh NAME
***************
*** 122,129 ****
  executable file.
  .It Er 9 EBADF Em "Bad file descriptor" .
  A file descriptor argument was out of range, referred to no open file,
! or a read (write) request was made to a file that was only open for
! writing (reading).
  .sp
  .It Er 10 ECHILD Em "\&No child processes" .
  A
--- 122,135 ----
  executable file.
  .It Er 9 EBADF Em "Bad file descriptor" .
  A file descriptor argument was out of range, referred to no open file,
! had been revoked by
! .Xr revoke 2 ,
! or a
! .Xr read 2
! (or
! .Xr write 2 )
! request was made to a file that was
! only open for writing (or reading).
  .sp
  .It Er 10 ECHILD Em "\&No child processes" .
  A
Index: src/lib/libc/sys/revoke.2
===================================================================
RCS file: /cvs/NetBSD/src/lib/libc/sys/revoke.2,v
retrieving revision 1.1.1.2
diff -c -c -r1.1.1.2 src/lib/libc/sys/revoke.2
*** src/lib/libc/sys/revoke.2	1998/11/16 20:38:48	1.1.1.2
--- src/lib/libc/sys/revoke.2	1999/03/22 06:37:27
***************
*** 36,42 ****
  .\"
  .\"     @(#)revoke.2	8.1 (Berkeley) 6/4/93
  .\"
! .Dd June 4, 1993
  .Dt REVOKE 2
  .Os
  .Sh NAME
--- 36,42 ----
  .\"
  .\"     @(#)revoke.2	8.1 (Berkeley) 6/4/93
  .\"
! .Dd March 22, 1999
  .Dt REVOKE 2
  .Os
  .Sh NAME
***************
*** 65,75 ****
  is called as if all open references to the file had been closed.
  .Pp
  Access to a file may be revoked only by its owner or the super user.
! The
  .Nm revoke
! function is currently supported only for block and character special
! device files.
! It is normally used to prepare a terminal device for a new login session,
  preventing any access by a previous user of the terminal.
  .Sh RETURN VALUES
  A 0 value indicated that the call succeeded.  A \-1 return value
--- 65,73 ----
  is called as if all open references to the file had been closed.
  .Pp
  Access to a file may be revoked only by its owner or the super user.
! .Pp
  .Nm revoke
! is normally used to prepare a terminal device for a new login session,
  preventing any access by a previous user of the terminal.
  .Sh RETURN VALUES
  A 0 value indicated that the call succeeded.  A \-1 return value
***************
*** 93,106 ****
  .It Bq Er EFAULT
  .Fa path
  points outside the process's allocated address space.
- .It Bq Er EINVAL
- The named file is neither a character special or block
- special file.
  .It Bq Er EPERM
  The caller is neither the owner of the file nor the super user.
  .El
  .Sh SEE ALSO
! .Xr close 2
  .Sh HISTORY
  The
  .Nm revoke
--- 91,107 ----
  .It Bq Er EFAULT
  .Fa path
  points outside the process's allocated address space.
  .It Bq Er EPERM
  The caller is neither the owner of the file nor the super user.
  .El
  .Sh SEE ALSO
! .Xr close 2 ,
! .Xr dup 2 ,
! .Xr fcntl 2 ,
! .Xr flock 2 ,
! .Xr fstat 2 ,
! .Xr read 2 ,
! .Xr write 2
  .Sh HISTORY
  The
  .Nm revoke
>Audit-Trail:
>Unformatted: