Commit Graph

286 Commits

Author SHA1 Message Date
Michael Kerrisk 50e5322c85 Added SEE ALSO reference to ftm.7 2006-04-21 06:49:34 +00:00
Michael Kerrisk 00d7bbcfbf Expanded discussion of mandatory locking. 2006-03-31 21:14:41 +00:00
Michael Kerrisk 1130df606b Amend copyright notices, in particular those where I had significant
authorship.
2006-02-15 23:15:29 +00:00
Michael Kerrisk 3adb464791 tfix 2006-02-13 22:46:01 +00:00
Michael Kerrisk 8548d8e240 Under ERRORS: Separate out EAGAIN error for locking mmaped files. 2006-02-10 20:29:38 +00:00
Michael Kerrisk c533af9d27 Reformatted FIXMEs 2006-02-10 18:46:42 +00:00
Michael Kerrisk 92057f4dbc Updated FIXMEs 2006-02-08 09:44:13 +00:00
Michael Kerrisk 1363cf9511 Added xref under dnotify description to inotify.7. 2006-02-06 22:43:15 +00:00
Michael Kerrisk 68b93ce208 Small wording changes 2006-02-02 03:25:50 +00:00
Michael Kerrisk b2216ffee6 Clarified parts of the discussion of file leases,
noting effect of open(O_NONBLOCK), interruption
by signal handler, or termination by signal in lease breaker.
In response to Debian bug 339037.
2005-11-17 14:56:41 +00:00
Michael Kerrisk 31e9a9ec99 Change itacised function names and page xrefs to bold 2005-11-02 11:34:24 +00:00
Michael Kerrisk 35e21ba7ca Formatting fixes 2005-10-19 13:48:50 +00:00
Michael Kerrisk a7a0588842 Further improvements to recently changed leases text 2005-10-13 09:30:54 +00:00
Michael Kerrisk 1a6d974a99 Since kernel 2.6.10, a read lease can only be placed on a
file descriptor that is opened read-only.
See the following LKML thread of Aug 2005
("fcntl(F GETLEASE) semantics??"):
http://marc.theaimsgroup.com/?l=linux-kernel&m=112371777712197&w=2
http://marc.theaimsgroup.com/?l=linux-kernel&m=112374818213000&w=2
http://marc.theaimsgroup.com/?l=linux-kernel&m=112376335305284&w=2
http://marc.theaimsgroup.com/?l=linux-kernel&m=112377294030092&w=2
2005-10-12 14:54:00 +00:00
Michael Kerrisk b14d4aa5b8 Classical BSD versions are now always named x.yBSD (formerly
there was a mix of x.yBSD and BSD x.y).
2005-07-18 15:05:56 +00:00
Michael Kerrisk 880f5b4bc3 Consistent use of "set-user-ID" and "set-group-ID". 2005-07-18 14:25:42 +00:00
Michael Kerrisk 8c383102d0 hyphen/dash fixes 2005-07-07 08:27:03 +00:00
Michael Kerrisk 8c45053412 s/the the/the/ 2005-07-05 13:50:51 +00:00
Michael Kerrisk 0847872439 Minor wording changes 2005-06-27 14:42:40 +00:00
Michael Kerrisk 98740ac7a7 Formatting changes 2005-06-24 10:53:06 +00:00
Michael Kerrisk 72da38ce1d Minor wording changes 2005-06-22 10:59:21 +00:00
Michael Kerrisk 1864073923 Added FIXME 2005-06-22 10:56:11 +00:00
Michael Kerrisk cff88e99ab Consistent use of terms "open file description",
"file status flags", and "file decriptor flags"
Some rewriting of discussion of file descriptor flags
Under F_DUPFD, replaced some text duplicated in dup.2 with a cross ref to dup.2
Minor wording and formatting fixes
2005-06-22 09:53:58 +00:00
Michael Kerrisk 8729177b44 global edit s/ -1/ \\-1/g 2005-06-15 14:10:23 +00:00
Michael Kerrisk 9d2a7b1f62 Noted F_SETOWN bug for socket file descriptor in Linux 2.4 and earlier.
Added text on permissions required to send signal to owner.

====

Hello Johannes,

> Betreff: Inaccuracy of fcntl man page
> Datum: Mon, 2 May 2005 20:07:12 +0200

Thanks for yor note.

Sorry for the delay in getting back to you.  I needed to find time 
to set aside to look at the details.  Now I've finally got there.

> I have attached a simple program 

Thanks -- a little program is always helpful.

> that uses the fcntl system call in order
> to kill an arbitrary process of the same user.
> According to the fcntl man page, fcntl(fd,F_SETOWN,pid) returns zero if 
> it has success.

Yes.

> If you strace the program while killing for exampe man running in another 
> terminal, you will see that man is killed, but fcntl(fd,F_SETOWN,pid)
> will return EPERM, 

I confirm that I see this problem in 2.4, with both Unix domain 
and Internet domain sockets.

> where you can only find a very confusing explanation 
> in the fcntl man page.

I'm not sure what explanation you mean here.  As far as I can 
tell, the manual page just doesn't cover this point.

> I have looked into the kernel source of 2.4.30 and found out, that 
> net/core/socket::sock_no_fcntl is the culprit if you use fcntl on Unix 
> sockets.

Yes, looks that way to me, as well,  And the 2.2 code looks 
similar.

> If pid is not your own pid or not your own process group, 
> the system call will return EPERM but will also set the pid 
> as you wanted to.

Yes.

> In the 2.6 kernel line, fcntl will react according the specification in
> the manual page.

Yes.

> If you also think, that one should clarify the return specification of 
> fcntl(fd,F_SETOWN,pid) or 2.4.x kernels, please tell me and I will 
> provide you with a patch for the manual page.

In fact I've written some new text under BUGS, which describes
the problem:

  In Linux 2.4 and earlier, there is bug that can occur  when  an
  unprivileged  process  uses  F_SETOWN to specify the owner of a
  socket file descriptor as a  process  (group)  other  than  the
  caller.   In this case, fcntl() can return -1 with errno set to
  EPERM, even when the owner process  (group)  is  one  that  the
  caller  has  permission to send signals to.  Despite this error
  return, the file descriptor owner is set, and signals  will  be
  sent to the owner.

Does that seem okay to you?

> Furthermore, it would be interseting to write there, what permissions 
> one need in order to send signals to processes via fcntl 

Good idea.  I added the following new text:

  Sending a signal to  the  owner  process  (group)  specified  by
  F_SETOWN  is  subject  to  the  same  permissions  checks as are
  described for kill(2), where the sending process is the one that
  employs F_SETOWN (but see BUGS below).

====


#define _GNU_SOURCE		/* needed to get the defines */
#include <fcntl.h>		/* in glibc 2.2 this has the needed
				   values defined */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>


/**
 * Funnykill kills a program with fcntl
**/
int
main (int argc, char **argv)
{
  if (argc != 2)
    {
      fprintf (stderr, "Usage: funnykill <pid>\n");
      return 1;
    }

  int sockets[2];
  socketpair (AF_UNIX, SOCK_STREAM, 0, sockets);
  if (fcntl (sockets[0], F_SETFL, O_ASYNC | O_NONBLOCK) == -1) 
      errMsg("fcntl-F_SETFL");
  if (fcntl (sockets[0], F_SETOWN, atoi (argv[1])) == -1) 
      errMsg("fcntl-F_SETOWN");
//  fcntl (sockets[0], F_SETOWN, getpid());
  if (fcntl (sockets[0], F_SETSIG, SIGKILL) == -1) 
      errMsg("fcntl-_FSETSIG");
  write (sockets[1], "good bye", 9);
}
2005-05-20 12:11:25 +00:00
Michael Kerrisk 704a18f06d Fixed typos and spelling mistakes 2005-04-18 13:35:29 +00:00
Michael Kerrisk 7502db97e2 Fix typo in 2.02 release 2005-04-14 09:24:26 +00:00
Michael Kerrisk 7c088cb1d8 Date: Fri, 28 Jan 2005 11:00:59 +0000
From: Jamie Lokier <jamie@shareable.org>
To: mtk-manpages@gmx.net
Subject: Update to fcntl(2) man page

Hi Michael,

I have a correction to the fcntl(2) man page.

Under the section for F_SETOWN, which describes how to set the
recipient process or group for SIGIO signals, see this paragraph:

	The process or process  group  to  receive  the  signal  can  be
	selected  by  using  the F_SETOWN command to the fcntl function.
	If the file descriptor is a socket, this also selects the recip-
	ient  of SIGURG signals that are delivered when out-of-band data
	arrives on that socket.  (SIGURG is sent in any situation  where
	select(2) would report the socket as having an "exceptional con-
	dition".)  If the file  descriptor  corresponds  to  a  terminal
	device,  then  SIGIO  signals are sent to the foreground process
	group of the terminal.

I would like to add an additional paragraph:

	The value given to F_SETOWN has a slightly different meaning
	when F_SETSIG is used in a multi-threaded process.

	If a non-zero value is given to F_SETSIG, then a positive
	value given to F_SETOWN identifies a specific thread within a
	process, instead of a whole process.  The value is a thread id
	not a process id, so you may need to pass the result of
	gettid() instead of getpid() to get sensible results when
	F_SETSIG is used.  (Thread ids are different from process ids,
	although they have the same value for some threads depending
	on details of the threading library used).

Also, this is the first paragraph of the F_SETSIG section:

	Sets the signal sent when input or output becomes  possible.   A
	value of zero means to send the default SIGIO signal.  Any other
	value (including SIGIO) is the signal to send  instead,  and  in
	this  case additional info is available to the signal handler if
	installed with SA_SIGINFO.

I'd like to append another paragraph right after that one:

	Additionally, passing a non-zero value to F_SETSIG changes the
	signal recipient from a whole process to a specific thread
	within a process.  The section on F_SETOWN gives more details.


Date: Thu, 7 Apr 2005 17:58:59 +0100
From: Jamie Lokier <jamie@shareable.org>
To: Michael Kerrisk <mtk-manpages@gmx.net>
Subject: Re: Update to fcntl(2) man page

[[...]]

> I've been trying to follow the kernel source code to verify
> the details you describe above.  The relevant place is the 
> 'switch' in fs/fcntl.c::send_sigio_to_task() right?

Yes.

> Also, for NPTL, perhaps one needs to mention that for the main
> thread, gettid() == getpid(), which allows the traditional
> use of F_SETSIG / F_SETOWN in programs consisting of a single
> thread -- right?

Yes, that makes sense.  It's also fine for the "main thread" with
NPTL, so programs which spawn threads can still use F_SETOWN/F_SETSIG
in the main thread using getpid().


Date: Tue, 12 Apr 2005 15:25:49 +0100
From: Jamie Lokier <jamie@shareable.org>
To: Michael Kerrisk <mtk-manpages@gmx.net>
Subject: Re: Update to fcntl(2) man page

Michael Kerrisk wrote:
>   F_SETOWN
>          Set  the  process ID or process group ID that will
>          receive SIGIO and SIGURG  signals  for  events  on
>          file  descriptor fd.  A process ID is specified as
>          a positive value; a process group ID is  specified
>          as a negative value.
> 
>          If  you  set  the  O_ASYNC  status  flag on a file
>          descriptor (either by providing this flag with the
>          open(2)  call,  or by using the F_SETFL command of
>          fcntl), a SIGIO signal is sent whenever  input  or
>          output  becomes  possible on that file descriptor.
>          F_SETSIG can be used to obtain delivery of a  sig&#8208;
>          nal other than SIGIO.
> 
>          If  the  file  descriptor  fd  refers to a socket,
>          F_SETOWN also selects the recipient of SIGURG sig&#8208;
>          nals  that  are  delivered  when  out-of-band data
>          arrives on that socket.  (SIGURG is  sent  in  any
>          situation  where select(2) would report the socket
>          as having an "exceptional condition".)
> 
>          If a non-zero value is  given  to  F_SETSIG  in  a
>          multi-threaded  process,  then  a  positive  value
>          value given to F_SETOWN has a  different  meaning:
>          instead  of being a process ID identifying a whole
>          process, it is a thread ID identifying a  specific
>          thread  within a process.  Consequently, it may be
>          necessary to pass F_SETOWN the result of  gettid()
>          instead  of  getpid() to get sensible results when
>          F_SETSIG is used.   (In  current  Linux  threading
>          implementations,  a main thread's thread ID is the
>          same as its process ID.  This means that a single-
>          threaded  program can equally use gettid() or get&#8208;
>          pid() in this scenario.)  Note, however, that  the
>          statements  in  this paragraph do not apply to the
>          SIGURG signal generated for out-of-band data on  a
>          socket:  this  signal  is  always sent to either a
>          process or a process group, depending on the value
>          given to F_SETOWN.
> 
> And the first part of the description of F_SETSIG now reads:
> 
>   F_SETSIG
>          Sets the signal sent when input or output  becomes
>          possible.   A  value  of  zero  means  to send the
>          default SIGIO signal.  Any other value  (including
>          SIGIO)  is the signal to send instead, and in this
>          case additional info is available  to  the  signal
>          handler if installed with SA_SIGINFO.
> 
>          Additionally, passing a non-zero value to F_SETSIG
>          changes the signal recipient from a whole  process
>          to  a  specific  thread within a process.  See the
>          desciption of F_SETOWN for more details.
> 
> Does the above seem okay to you?

It looks good, but: 

  1. An omission: It mentions that SIGURG is always sent to the whole
     process.  SIGIO is also sent to the whole process, instead of
     queueing a thread-specific signal, when the signal queue is full.
     Programs that mustn't miss readiness events need to handle it.

  2. The description could be confusing to LinuxThreads users, because
     all the signals are thread-specific in LinuxThreads.


Date: Tue, 12 Apr 2005 16:53:19 +0100
From: Jamie Lokier <jamie@shareable.org>
To: Michael Kerrisk <mtk-manpages@gmx.net>
Subject: Re: Update to fcntl(2) man page

Michael Kerrisk wrote:
> >   1. An omission: It mentions that SIGURG is always sent to the whole
> >      process.  SIGIO is also sent to the whole process, instead of
> >      queueing a thread-specific signal, when the signal queue is full.
> >      Programs that mustn't miss readiness events need to handle it.
> 
> Sorry -- can you point me to the relevant code for the 
> above point please.

In 2.6:

	switch (fown->signum) {
		siginfo_t si;
		default:
			/* Queue a rt signal with the appropriate fd as its
			   value.  We use SI_SIGIO as the source, not 
			   SI_KERNEL, since kernel signals always get 
			   delivered even if we can't queue.  Failure to
			   queue in this case _should_ be reported; we fall
			   back to SIGIO in that case. --sct */
			si.si_signo = fown->signum;
			si.si_errno = 0;
		        si.si_code  = reason;
			/* Make sure we are called with one of the POLL_*
			   reasons, otherwise we could leak kernel stack into
			   userspace.  */
			if ((reason & __SI_MASK) != __SI_POLL)
				BUG();
			if (reason - POLL_IN >= NSIGPOLL)
				si.si_band  = ~0L;
			else
				si.si_band = band_table[reason - POLL_IN];
			si.si_fd    = fd;
			if (!send_sig_info(fown->signum, &si, p))
				break;
		/* fall-through: fall back on the old plain SIGIO signal */
		case 0:
			send_group_sig_info(SIGIO, SEND_SIG_PRIV, p);

2.4 is exactly the same, except:

		/* fall-through: fall back on the old plain SIGIO signal */
		case 0:
			send_sig(SIGIO, p, 1);

The fall-through happens when send_sig_info() fails, which happens
when the real-time signal queue is full.

Programs using a queued signal to track file readiness efficiently (as
an alternative to select/poll), must listen for SIGIO in addition to
the real-time signal, as otherwise they will miss notifications when
the queue is full (which happens often on a busy server).

Multi-threaded programs using NPTL must be aware this SIGIO is
process-wide - so receiving it on one thread must cause all threads to
assume a queued signal may be lost.  Programs using LinuxThreads do
not have to assume this (but it's safe if they do).


Date: Wed, 13 Apr 2005 17:25:44 +0100
From: Jamie Lokier <jamie@shareable.org>
To: Michael Kerrisk <mtk-manpages@gmx.net>
Subject: Re: Update to fcntl(2) man page

Michael Kerrisk wrote:
> I added a few more sentences to the end of that paragraph
> on F_SETOWN:
> 
>     If a non-zero value is given  to  F_SETSIG  in  a multi-threaded
>     process  running with  a threading  library that supports thread
>     groups (e.g., NPTL),  then  a  positive  value  value  given to
>     F_SETOWN has a different meaning: instead  of being a process ID
>     identifying a whole  process, it is a  thread  ID identifying  a
>     specific thread  within a process.  Consequently, it may be nec-
>     essary to pass  F_SETOWN the result of gettid() instead  of  get
>     pid() to  get sensible results  when F_SETSIG is used.  (In cur-
>     rent Linux threading implementations, a main thread's thread  ID
>     is  the  same  as  its  process  ID.   This means that a single-
>     threaded program can equally use gettid() or  getpid()  in  this
>     scenario.)  Note, however, that the statements in this paragraph
>     do not apply to the SIGURG signal generated for out-of-band data
>     on a socket: this signal is always sent to either a process or a
>     process group, depending on the value given to  F_SETOWN.   Note
>     also  that Linux imposes a limit on the number of real-time sig-
>     nals that may be queued to a process (see getrlimit(2) and  sig-
>     nal(7)) and if this limit is reached, then the kernel reverts to
>     delivering SIGIO, and  this  signal is  delivered to the  entire 
>     process rather than to a specifc thread.
> 
> Look oay now?

Looks ood.

It will take a minor genius to translate that to working
multi-threaded RT-SIGIO code without a tutorial -- and in fact I
haven't heard of any program or library which does it (though I'm
trying to write one) -- but technically it seems to include everything.
2005-04-05 05:54:09 +00:00
Michael Kerrisk 2f36a80706 Jamie Lokier / mtk
Improved discussion of F_SETOWN and F_SETSIG with respect to
multi-threaded programs.

Generally cleaned up the discussion of F_SETOWN.
2005-04-08 13:42:00 +00:00
Michael Kerrisk 8505c1f1d6 Date: Mon, 13 Dec 2004 12:09:43 +0100 (MET)
From: "Michael Kerrisk" <mtk-manpages@gmx.net>
To: Andries Brouwer <Andries.Brouwer@cwi.nl>
Subject: Re: errno

Hi Andries,

> On Fri, Dec 10, 2004 at 05:07:36PM +0100, Michael Kerrisk wrote:
> 
> > I added this text to fcntl.2:
> > 
> >     BUGS
> >        A  limitation of the Linux system call conventions means that
> >        if a (negative) process group ID to be returned  by  F_GETOWN
> >        falls  in  the  range  -1  to -4095, then the return value is
> >        wrongly interpreted by glibc as an error in the system  call;
> >        that  is,  the  return value of fcntl() will be -1, and errno
> >        will contain the (positive) process group ID.
> 
> Yes.
> 
> (Maybe glibc always did this, early libc considered any negative
> return value an error. On the other hand, not all the world is an i386 -
> IBM has just decided that we don't need any i386's anymore
> and sold their stuff to the Chinese - we must use PPC, as Linus
> does already - and on other architectures we do not have this
> ugliness, I think.)
> 
> You might consider adding "i386" somewhere:
>  A limitation of the Linux i386 system call conventions ...

Some testing on ia64 (RedHat EL 3.0, 2.4.21) and 
alpha (2.4.18, Debian 3.0) showed that any negative PGID value
causes F_GETOWN to fail.

My limited reading of the ia64 source:

sysdeps/unix/sysv/linux/ia64/sysdep.h

shows that there is a comment about the -4095 value there, 
but that doesn't seem to reflect the reality of the code.

Reading the source, the -4095 limit seems to hold on some 
other architectures, e.g.:

sysdeps/unix/sysv/linux/m68k/sysdep.h
sysdeps/unix/sysv/linux/hppa/sysdep.h
sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
sysdeps/unix/sysv/linux/x86_64/sysdep.h

Unfortunately, I have no non-x86 systems other than the above 
alpha and ia64 (HP-testdrive) on which I can test.

I modified the text a little:

   BUGS
       A  limitation  of the Linux system call conventions on some
       architectures (notably x86) means that if a (negative) pro&#8208;
       cess group ID to be returned by F_GETOWN falls in the range
       -1 to -4095, then the return value is  wrongly  interpreted
       by  glibc  as  an  error  in  the system call; that is, the
       return value of fcntl() will be -1, and errno will  contain
       the (positive) process group ID.

I've left a FIXME in the man page source noting that details have
yet to be sorted out for ia64, alpha, etc.
2004-12-13 11:32:37 +00:00
Michael Kerrisk 0ff184704f [Further notes on that F_GETOWN bug]
Hi Andries,

[Just for my own  reference, I reinclude the pointer to Philippe 
Troin's patch
http://marc.theaimsgroup.com/?l=linux-kernel&m=108380640603164&w=2
]

> > > Except of course for fcntl(fd, F_GETOWN) where the owner is a
> > > (negative) process group... If the owning process group has a "low
> > > enough" PGID, it collides with errors and glibc reports an error and
> > > sets errno to -PGID. One might argue that in this instance, that the
> > > BSD's overloading of the pid field with pgids is at fault, but the 
> > > bug
> > > still remains :-)
> > 
> > I believe that practically speaking this is a non-issue.  The 
> > lowest PID / PGID that can be allocated to a process other than 
> > init or a kernel thread is 300.  (RESERVED_PID in kernel/pid.c 
> > in 2.6, details differ, but same limit in <= 2.4.)
> 
> Hmm. RESERVED_PIDS is used as starting value after overflow,
> not as a starting value at the beginning. I think you are mistaken.

Hmm -- yes.  And I was in any case assuming the notion
of a process that might do an F_SETOWN assigning
its own PGID to the socket -- but that might not be so.

And I was overlooking a comment in the fs/fcntl.c 
sources that reiterates the point:

        case F_GETOWN:
                /*
                 * XXX If f_owner is a process group, the
                 * negative return value will get converted
                 * into an error.  Oops.  If we keep the
                 * current syscall conventions, the only way
                 * to fix this will be in libc.
                 */
                err = filp->f_owner.pid;
                force_successful_syscall_return();
                break;

And now I've actually created the error in userland code.
It seems that whenever the -PGID retrieved by F_GETOWN is 
smaller than 4096, then it is interpreted as an error.

Now I see the relevant code in 
sysdeps/unix/sysv/linux/i386/sysdep.h:

==
/* Linux uses a negative return value to indicate syscall errors,
   unlike most Unices, which use the condition codes' carry flag.

   Since version 2.1 the return value of a system call might be
   negative even if the call succeeded.  E.g., the `lseek' system call
   might return a large offset.  Therefore we must not anymore test
   for < 0, but test for a real error by making sure the value in %eax
   is a real error number.  Linus said he will make sure the no syscall
   returns a value in -1 .. -4095 as a valid result so we can savely
   test with -4095.  */

[...]
    DO_CALL (syscall_name, args);
    cmpl $-4095, %eax;          
    jae SYSCALL_ERROR_LABEL;    

==

Ugh.
2004-12-10 16:28:25 +00:00
Michael Kerrisk 7c3b0e957d noted F_GETOWN bug after suggestion from aeb. 2004-12-10 16:26:28 +00:00
Michael Kerrisk 1c1e15ed85 Martin Pool (and mtk) -- added O_NOATIME 2004-12-08 16:41:10 +00:00
Michael Kerrisk 1c287bbf01 fix typo 2004-12-06 13:39:28 +00:00
Michael Kerrisk 305a0578bf Global change of email address for MTK (now: mtk-manpages@gmx.net) 2004-11-03 14:43:40 +00:00
Michael Kerrisk fea681dafb Import of man-pages 1.70 2004-11-03 13:51:07 +00:00